我想在MySQL数据库中取出重复的记录。这可以用:
SELECT address, count(id) as cnt FROM list
GROUP BY address HAVING cnt > 1
结果是:
100 MAIN ST 2
我想要拖动它,以便它显示复制的每一行。喜欢的东西:
JIM JONES 100 MAIN ST
JOHN SMITH 100 MAIN ST
有什么想法可以做到吗?我试图避免做第一个,然后在代码中用第二个查询查找重复。
这将在一次表传递中选择重复项,没有子查询。
SELECT *
FROM (
SELECT ao.*, (@r := @r + 1) AS rn
FROM (
SELECT @_address := 'N'
) vars,
(
SELECT *
FROM
list a
ORDER BY
address, id
) ao
WHERE CASE WHEN @_address <> address THEN @r := 0 ELSE 0 END IS NOT NULL
AND (@_address := address ) IS NOT NULL
) aoo
WHERE rn > 1
这个查询实际上模拟了Oracle和SQL Server中的ROW_NUMBER()
详见我博客上的文章:
分析函数:SUM, AVG, ROW_NUMBER -在MySQL模拟。
这里的大多数答案不适用于有多个重复结果和/或有多个列要检查重复的情况。当你在这种情况下,你可以使用这个查询来获得所有重复的id:
SELECT address, email, COUNT(*) AS QUANTITY_DUPLICATES, GROUP_CONCAT(id) AS ID_DUPLICATES
FROM list
GROUP BY address, email
HAVING COUNT(*)>1;
如果希望将每个结果作为一行列出,则需要更复杂的查询。这是我发现有效的方法:
CREATE TEMPORARY TABLE IF NOT EXISTS temptable AS (
SELECT GROUP_CONCAT(id) AS ID_DUPLICATES
FROM list
GROUP BY address, email
HAVING COUNT(*)>1
);
SELECT d.*
FROM list AS d, temptable AS t
WHERE FIND_IN_SET(d.id, t.ID_DUPLICATES)
ORDER BY d.id;
要快速查看重复的行,可以运行一个简单的查询
在这里,我正在查询表,并列出所有重复的行相同的user_id, market_place和sku:
select user_id, market_place,sku, count(id)as totals from sku_analytics group by user_id, market_place,sku having count(id)>1;
要删除重复的行,必须决定要删除哪一行。例如id较低(通常较旧)或其他日期信息。在我的情况下,我只是想删除较低的id,因为较新的id是最新的信息。
首先仔细检查是否正确的记录将被删除。在这里,我正在选择将被删除的副本中的记录(通过唯一id)。
select a.user_id, a.market_place,a.sku from sku_analytics a inner join sku_analytics b where a.id< b.id and a.user_id= b.user_id and a.market_place= b.market_place and a.sku = b.sku;
然后我运行delete查询来删除dupes:
delete a from sku_analytics a inner join sku_analytics b where a.id< b.id and a.user_id= b.user_id and a.market_place= b.market_place and a.sku = b.sku;
备份,双重检查,验证,验证备份,然后执行。