如何仅按单列分组并去除SN重复值?SQL执行报错求助
解决PostgreSQL中DISTINCT ON与GROUP BY冲突的问题
问题原因分析
你遇到的报错是PostgreSQL严格的分组规则导致的:当使用GROUP BY时,SELECT列表里的非聚合列必须要么出现在GROUP BY子句中,要么被聚合函数(比如count()、max())包裹。而你的SQL同时混用了DISTINCT ON (sn)和GROUP BY Failed_operation,这两个逻辑本质是冲突的:
DISTINCT ON (sn)是为每个唯一的sn保留一行数据GROUP BY Failed_operation是把所有相同Failed_operation的行聚合在一起
数据库无法确定在每个Failed_operation分组里应该选取哪个sn的值,因此抛出了这个错误。而去掉DISTINCT ON (sn)后,每个sn的多条记录都会被计入统计,自然会出现重复的sn。
解决方案
根据你的需求(按Failed_operation分组,同时每个sn只被统计一次),我们可以先通过子查询获取去重后的sn与Failed_operation的关联数据,再进行分组统计。这里假设你需要每个sn只保留最新的那条故障记录(如果不需要最新的,可去掉ORDER BY里的fail_timestamp DESC):
SELECT Failed_operation, COUNT(CASE WHEN aging_days > 0 AND aging_days <= 15 THEN 1 END) AS AgingLessThan15, COUNT(CASE WHEN aging_days > 15 AND aging_days <= 30 THEN 1 END) AS Aging16To30, COUNT(CASE WHEN aging_days > 30 AND aging_days <= 60 THEN 1 END) AS Aging31To60, COUNT(CASE WHEN aging_days > 60 THEN 1 END) AS AgingGreaterThan60, COUNT(CASE WHEN aging_days <= 0 THEN 1 END) AS Aging0 FROM ( -- 子查询:每个sn只保留一条记录(这里取最新的故障时间对应的记录) SELECT DISTINCT ON (sn) sn, Failed_operation, EXTRACT(DAY FROM NOW() - fail_timestamp) AS aging_days FROM rw_pcba WHERE rework_status = 'In-Process' ORDER BY sn, fail_timestamp DESC -- 按sn排序,确保每个sn只留最新的那条 ) AS unique_sn_records GROUP BY Failed_operation ORDER BY Failed_operation ASC;
额外说明
如果你的场景是每个sn可能对应多个不同的Failed_operation,且需要在每个Failed_operation分组里都对该sn去重,只需要把子查询里的DISTINCT ON (sn)改成DISTINCT ON (sn, Failed_operation)即可。
内容的提问来源于stack exchange,提问作者Wannisa Cheamsiri
相关产品推荐
相关产品推荐

