Лучший способ перенести таблицу MySQL с дупю на другой стол с уникальным ограничением

StackOverflow https://stackoverflow.com/questions/3632350

Вопрос

Я пытаюсь выработать лучший подход к миграции данных.

Я мигрирую некоторые данные (~ 8000 строк) из таблицы, как это:

CREATE TABLE location (
    location_id INT NOT NULL AUTO_INCREMENT UNIQUE PRIMARY KEY,
    addr VARCHAR(1000) NOT NULL,
    longitude FLOAT(11),
    latitude FLOAT(11)
) Engine = InnoDB, DEFAULT CHARSET=UTF8;

в таблицу, как это:

CREATE TABLE location2 (
    location_id INT NOT NULL AUTO_INCREMENT UNIQUE PRIMARY KEY,
    addr VARCHAR(255) NOT NULL UNIQUE,
    longitude FLOAT(11),
    latitude FLOAT(11)
) Engine = InnoDB, DEFAULT CHARSET=UTF8;

Не важно сохранить первичный ключ.

Адреса в «местоположении» дублируются много раз. В большинстве случаев с такой же широтой и долготой. Но в некоторых случаях есть строки с одинаковым значением для ADDR, но разных ценностей для широты и долготы.

В таблице Final Location2 должна иметь одну запись для каждой уникальной записи ADDR в месте. Там, где следует использовать более одного возможного значения для широты / долготы, новейшее (самое высокое местоположение_id) следует использовать.

Я создал процедуру, чтобы сделать это, но это не понравится строки, где addr такой же, но широта / долгота разные.

DROP PROCEDURE IF EXISTS migratelocation;
DELIMITER $$
CREATE PROCEDURE migratelocation()
BEGIN
    DECLARE done INT DEFAULT 0;
    DECLARE a VARCHAR(255);
    DECLARE b, c FLOAT(11);
    DECLARE cur CURSOR FOR SELECT DISTINCT addr, latitude, longitude FROM location;
    DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = 1;
    OPEN cur;
    REPEAT
        FETCH cur INTO a, b, c;
        IF NOT done THEN
            INSERT INTO location2 (addr, latitude, longitude) VALUES (a, b, c);
        END IF;
    UNTIL done END REPEAT;
    CLOSE cur;
END $$
DELIMITER ;
CALL migratelocation();

Есть хороший способ сделать это? Я продолжаю хотеть сдаться и написать немного PHP PROG, чтобы сделать это, но я предпочел бы узнать правильный путь SQL, если смогу.

Возможно, мне просто нужно найти правильный выбор из первой таблицы, и я могу использовать:

INSERT INTO location2 SELECT ... ;

мигрировать данные.

Спасибо!

Это было полезно?

Решение

Вы можете использовать INSERT IGNORE напрямую, или ЗАМЕНЯТЬ - Я предполагаю, что это односторонний процесс, или, по крайней мере, один, где производительность не является основным соображением.

В этом случае запись с наивысшим местоположением_ид WINS:

INSERT IGNORE
INTO   location2
SELECT *
FROM   location
ORDER BY
       location_id DESC

Последующие записи остроумие одинаковое значение первичного ключа просто отбрасываются вставкой.

Вам нужно будет отключить строгий режим SQL, в противном случае усечение поля ADDR даст ошибки.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top