我正在处理的表格有多行,lat
和lon
的值相同。该示例显示1
,3
,5
具有相同的位置,但name
属性不同。 hash
由name
,lat
和lon
构建,因此不同。
BEFORE:
id | name | lat | lon | flag | hash
----+------+-----+-----+------+------
1 | aaa | 16 | 48 | 0 | 2cd <-- duplicate
2 | bbb | 10 | 22 | 0 | 3fc
3 | ccc | 16 | 48 | 0 | 8ba <-- duplicate
4 | ddd | 10 | 23 | 0 | c33
5 | eee | 16 | 48 | 0 | 751 <-- duplicate
我需要在此表中标识“重复”,并希望将标记1
(主)分配给其中一个标记2
(次要)给其他人。将“复制”标记为 primary 并不重要。
AFTER:
id | name | lat | lon | flag | hash
----+------+-----+-----+------+------
1 | aaa | 16 | 48 | 1 | 2cd <-- updated
2 | bbb | 10 | 22 | 0 | 3fc
3 | ccc | 16 | 48 | 2 | 8ba <-- updated
4 | ddd | 10 | 23 | 0 | c33
5 | eee | 16 | 48 | 2 | 751 <-- updated
我开始尝试INNER JOIN
inspired by this post和此visual description。有了这个,我可以为所有重复项分配相同的标志。
UPDATE table t1
INNER JOIN table_name t2
ON
t1.lat = t2.lat
AND t1.lon = t2.lon
AND t1.hash != t2.hash
SET
t1.flag = 2;
我还使用LEFT OUTER JOIN
测试了WHERE t2.id IS NULL
,当只有两行时,它可以正常工作。但是,我无法想象JOIN
应如何处理多于两个重复。 Mark Harrison还假设“您正在加入没有重复的列” at the beginning of his post,这听起来好像这不是一个好主意。
如果感兴趣,我正在使用MySQL。
答案 0 :(得分:2)
不确定这是非常有效的,但works in just one query:
UPDATE t
JOIN (
SELECT MAX(t.id) AS maxid, lat, lon
FROM t
JOIN t AS duplicates
USING (lat, lon)
GROUP BY lat, lon
HAVING COUNT(*) > 1
) AS maxima USING (lat, lon)
SET flag = IF(id = maxid, 1, 2);
答案 1 :(得分:0)
假设您希望所有规范记录都有flag=1
(而不仅仅是那些具有重复记录的记录),您可以这样做:
UPDATE table t1
SET t1.flag = 1
WHERE t1.id in (
SELECT min(id)
FROM table t2
WHERE t1.lat = t2.lat
AND t1.lon = t2.lon
);
UPDATE table
SET flag = 2
WHERE flag is null;
COMMIT;
答案 2 :(得分:0)
您可以分两步完成此操作:
update table t1 set flag = 2 where id in
(select a.id
from
t1 a
join t1 b on (b.lon = a.lon and b.lat = a.lat));
update table t1 set flag = 1 where id in
(select a.id
from t1 a
where a.flag = 2 and a.id =
(select min(b.id) from t1 b where b.lon = a.lon and b.lat = a.lat)
);
这应该被用作灵感,不是作为福音(可能是错的):)