編集:私の以前の回答で、に一意の制約が必要であることを提案しました(id, version)
が、実際にはこれは必要ありません。ソリューションが機能するには、のみに対する独自の制約でid
十分です。
REPLACE
次のようにコマンドを使用できるはずです。
REPLACE INTO main
SELECT IFNULL(m.id, s.id) id,
IFNULL(m.version, s.version) version,
IFNULL(m.data, s.data) data
FROM secondary s
LEFT JOIN main m ON (m.id = s.id AND m.version > s.version);
テストケース:
CREATE TABLE main (
id int,
version int,
data varchar(50),
PRIMARY KEY (id)
);
CREATE TABLE secondary (id int, version int, data varchar(50));
INSERT INTO main VALUES (1, 3, 'first data set');
INSERT INTO main VALUES (2, 2, 'second data set');
INSERT INTO main VALUES (3, 5, 'third data set');
INSERT INTO secondary VALUES (1, 4, 'updated 1st');
INSERT INTO secondary VALUES (3, 3, 'udated 2nd');
INSERT INTO secondary VALUES (4, 1, 'new 4th');
結果:
SELECT * FROM main;
+----+---------+-----------------+
| id | version | data |
+----+---------+-----------------+
| 1 | 4 | updated 1st |
| 2 | 2 | second data set |
| 3 | 5 | third data set |
| 4 | 1 | new 4th |
+----+---------+-----------------+
4 rows in set (0.00 sec)
REPLACE
補足として、そのコマンドで何が起こっているかを理解しやすくするために、次の点に注意してください。
SELECT s.id s_id, s.version s_version, s.data s_data,
m.id m_id, m.version m_version, m.data m_data
FROM secondary s
LEFT JOIN main m ON (m.id = s.id AND m.version > s.version);
+------+-----------+-------------+------+-----------+----------------+
| s_id | s_version | s_data | m_id | m_version | m_data |
+------+-----------+-------------+------+-----------+----------------+
| 1 | 4 | updated 1st | NULL | NULL | NULL |
| 3 | 3 | udated 2nd | 3 | 5 | third data set |
| 4 | 1 | new 4th | NULL | NULL | NULL |
+------+-----------+-------------+------+-----------+----------------+
3 rows in set (0.00 sec)
次に、IFNULL()
id = 3、version = 5の場合のように、メインテーブルから最新バージョンが存在する場合、関数は最新バージョンを「上書き」していました。したがって、次のようになります。
SELECT IFNULL(m.id, s.id) id,
IFNULL(m.version, s.version) version,
IFNULL(m.data, s.data) data
FROM secondary s
LEFT JOIN main m ON (m.id = s.id AND m.version > s.version);
+------+---------+----------------+
| id | version | data |
+------+---------+----------------+
| 1 | 4 | updated 1st |
| 3 | 5 | third data set |
| 4 | 1 | new 4th |
+------+---------+----------------+
3 rows in set (0.00 sec)
上記の結果セットにはセカンダリテーブルのレコードのみが含まれていますが、これらのレコードのいずれかがメインテーブルに新しいバージョンを持っている場合、行はメインテーブルのデータで上書きされます。これは、REPLACE
コマンドにフィードする入力です。