如何查询IdMod、TableName、FieldName三列重复的数据行?
如何查询多列组合重复出现两次及以上的数据行
看起来你已经找对了核心思路——先定位重复的列组合,再关联原表拿到完整数据,不过你的语句没写完,我帮你补全并详细解释下:
你的需求是从Process表中,提取IdMod、TableName、FieldName三列组合出现2次及以上的所有数据行,完整的SQL语句如下:
SELECT DISTINCT aa.Id, aa.IdMod, aa.TableName, aa.FieldName, aa.OldValue, aa.NewValue, aa.Origin, aa.Destination, aa.CreationDate, aa.Discard FROM Process aa INNER JOIN ( SELECT IdMod, TableName, FieldName FROM Process GROUP BY IdMod, TableName, FieldName HAVING COUNT(*) > 1 ) bb ON aa.IdMod = bb.IdMod AND aa.TableName = bb.TableName AND aa.FieldName = bb.FieldName;
语句逻辑拆解:
- 子查询
bb:通过GROUP BY对IdMod、TableName、FieldName这三列分组,再用HAVING COUNT(*) > 1筛选出出现次数超过1次的列组合,相当于先拿到所有"重复的标识"。 - 主查询:将原表
Process(别名aa)和子查询bb做内连接,只保留那些匹配到重复组合的行;加上DISTINCT是为了避免原表存在完全重复行时,结果里出现冗余数据。
如果你的数据库支持窗口函数(比如MySQL 8+、PostgreSQL、SQL Server等),还可以用更简洁的写法:
SELECT Id, IdMod, TableName, FieldName, OldValue, NewValue, Origin, Destination, CreationDate, Discard FROM ( SELECT *, COUNT(*) OVER (PARTITION BY IdMod, TableName, FieldName) AS repeat_count FROM Process ) t WHERE repeat_count > 1;
这种写法用窗口函数COUNT(*) OVER (PARTITION BY ...)直接计算每个列组合的出现次数,再筛选次数大于1的行,不需要做表连接,逻辑更直观易读。
内容的提问来源于stack exchange,提问作者Jmyebenes
相关产品推荐
相关产品推荐

