2

私はデータ移行のための最良のアプローチを考え出そうとしています。

次のようなテーブルからいくつかのデータ(〜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の値は同じで、緯度と経度の値が異なる行があります。

最終的なlocation2テーブルには、location内の一意のaddrエントリごとに1つのエントリが必要です。緯度/経度に複数の可能な値がある場合は、最新の(最大のlocation_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プログラムを書きたいと思っていますが、可能であれば、正しいSQLの方法を学びたいと思っています。

おそらく、最初のテーブルから適切なSELECTを見つける必要があり、次を使用できます。

INSERT INTO location2 SELECT ... ;

データを移行します。

ありがとう!

4

1 に答える 1

4

INSERT IGNOREを直接使用することも、REPLACEを使用することもできます。これは1回限りのプロセスであるか、パフォーマンスが主要な考慮事項ではない場合は少なくとも1つであると想定しています。

この場合、location_idが最も高いレコードが優先されます。

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

同じ主キー値を持つ後続のレコードは、挿入によって破棄されます。

厳密なSQLモードを無効にする必要があります。そうしないと、addrフィールドを切り捨てるとエラーが発生します。

于 2010-09-03T01:13:26.280 に答える