MySQL过滤product表重复行时现有SQL未生效,该如何实现去重?
MySQL 过滤product表重复数据解决方案
原有SQL失效原因
你的SQL仅对date字段做了去重后关联回原表,没有覆盖item维度的重复判断逻辑,每个date对应的所有item记录(含同date同item的重复行)都会被完整保留,因此不会产生去重效果。
需求实现方案
场景1:仅查询获取去重结果,不修改原表数据
方案1:仅需要返回date、item两个字段的唯一组合
直接对两个字段共同去重即可:
SELECT DISTINCT `date`, item FROM product;
方案2:表存在其他字段,需要保留每个(date, item)组合对应的完整行记录
MySQL 8.0+ 版本(支持窗口函数)
用ROW_NUMBER()窗口函数给每个(date, item)组合的行打标,取每组的第一条即可:
WITH ranked_products AS ( SELECT *, -- 按date+item分组,组内行编号,ORDER BY可自定义保留规则,比如按自增id倒序保留最新插入的行 ROW_NUMBER() OVER (PARTITION BY `date`, item ORDER BY (SELECT 1)) AS rn FROM product ) SELECT * FROM ranked_products WHERE rn = 1;
如果需要指定保留行的规则,可将ORDER BY (SELECT 1)替换为对应的排序逻辑,比如ORDER BY id DESC保留每组最新插入的记录
MySQL 5.x 版本(不支持窗口函数)
通过子查询先筛选出每个(date, item)组合需要保留的行主键,再关联回原表获取完整数据:
SELECT p.* FROM product p INNER JOIN ( -- 假设表存在自增主键id,取每组id最小的行作为保留行 SELECT MIN(id) AS keep_id FROM product GROUP BY `date`, item ) t ON p.id = t.keep_id;
场景2:直接删除原表中的重复数据,永久保留唯一记录
执行以下SQL即可删除重复行,每个(date, item)组合仅保留id最小的1条记录:
DELETE p1 FROM product p1 JOIN product p2 ON p1.`date` = p2.`date` AND p1.item = p2.item AND p1.id > p2.id;
执行删除操作前建议先备份数据,避免误删
内容的提问来源于stack exchange,提问作者Jorgefilemon
相关产品推荐
相关产品推荐

