我遇到了一个问题,实际上是一个关于如何根据第一个SELECT的名称和时间戳删除MySQL表中所有重复项的最简单方法的问题。
所以,我有这张桌子:
SELECT * FROM search;
+------+--------+------------+--------------------------+-----------------------+
| id | uid | string | cat | timestamp |
+------+--------+------------+--------------------------+-----------------------+
|39523 | 87 |eat to live | a:1:{i:0;s:5:"toate";} | 2013-10-07 17:01:41 |
|39524 | 87 |eat to live | s:6:"author"; | 2013-10-07 17:01:41 |
|39525 | 87 |eat to live | s:6:"people"; | 2013-10-07 17:01:41 |
|39526 | 87 |eat to live | s:7:"company"; | 2013-10-07 17:01:41 |
|39527 | 87 |eat to live | s:6:"author"; | 2013-10-07 17:01:42 |
|39532 | 31 | friends | a:1:{i:0;s:5:"toate";} | 2013-10-07 17:04:17 |
|39533 | 31 | friends | s:6:"people"; | 2013-10-07 17:04:17 |
|39534 | 31 | friends | s:7:"company"; | 2013-10-07 17:04:17 |
|39535 | 31 | friends | s:6:"author"; | 2013-10-07 17:04:17 |
+------+--------+------------+--------------------------+-----------------------+
我想只留下第一个独特的外观。我的解决方案是选择所有行,通过'它们,并为每一行删除匹配相同字符串的所有行,相同的uid和时间戳为相同的时间戳或+1秒。
有什么想法/建议?我可以在PHP中执行此操作,并且想知道是否有更简单的方法直接使用SQL查询执行此操作。
由于
答案 0 :(得分:3)
MySQL支持多表DELETE,因此您可以执行自连接,以便只删除具有更大ID的行。
DELETE s2
FROM search AS s1 JOIN search AS s2
ON s1.string = s2.string AND s1.uid = s2.uid AND s1.id < s2.id;
如果你想为连接添加一些逻辑,那么只有当匹配的s2
行与第一行相距不超过1秒时才会删除它,你也可以这样做:
DELETE s2
FROM search AS s1 JOIN search AS s2
ON s1.string = s2.string AND s1.uid = s2.uid AND s1.id < s2.id;
AND s2.timestamp <= s1.timestamp+1
但是如果你连续有多个条目,每个条目间隔1秒,这将删除除第一个之外的所有条目。我不确定在那种情况下你想做什么。
答案 1 :(得分:0)
您可以使用此代码删除,基于副本是具有相同 uid 和字符串的副本;这段代码只会留下第一次出现。
DELETE FROM search
WHERE id NOT IN
(SELECT MIN(id) FROM search GROUP BY uid, string);