SQL查询需求:按特定条件返回唯一行并排除指定重复数据
解决SQL查询排除特定重复行的问题
我来帮你搞定这个SQL查询需求!你想要返回唯一行,但要排除那些**有重复水果名称且其中至少一行状态是'Approved'**的所有相关行,对吧?而且同一水果最多只有两行数据,那咱们可以这样来实现:
你现在写的SELECT DISTINCT * FROM Food;只能做简单去重,但没法识别并排除那些带Approved状态的重复水果,所以得换个思路。
方案一:用子查询筛选要排除的水果
这是兼容性比较好的写法,大部分数据库都支持:
SELECT DISTINCT * FROM Food WHERE fruit_name NOT IN ( -- 找出需要排除的水果:有重复行且至少一行是Approved SELECT fruit_name FROM Food GROUP BY fruit_name HAVING COUNT(*) > 1 AND SUM(CASE WHEN status = 'Approved' THEN 1 ELSE 0 END) > 0 );
逻辑解释
- 子查询里,我们按水果名称分组,筛选出两个条件都满足的水果:
COUNT(*) > 1:这个水果有重复行(最多两行)SUM(CASE...) > 0:分组里至少有一行状态是Approved
- 主查询只保留那些不在这个排除列表里的水果行,再用
DISTINCT确保结果唯一。
方案二:用窗口函数(适合MySQL8+、PostgreSQL等)
如果你的数据库支持窗口函数,写法会更直观:
WITH fruit_status AS ( SELECT *, -- 统计每个水果的总行数 COUNT(*) OVER (PARTITION BY fruit_name) AS total_rows, -- 判断该水果是否有Approved的行 MAX(CASE WHEN status = 'Approved' THEN 1 ELSE 0 END) OVER (PARTITION BY fruit_name) AS has_approved FROM Food ) SELECT DISTINCT * FROM fruit_status -- 保留两种情况:只有一行的水果,或者有两行但没有Approved的水果 WHERE total_rows = 1 OR (total_rows = 2 AND has_approved = 0);
逻辑解释
- 先通过CTE给每一行加上两个额外字段:
total_rows是该水果的总行数,has_approved标记这个水果有没有Approved状态的行 - 然后筛选出符合要求的行,最后用
DISTINCT确保结果唯一
这样写出来的查询就能完全满足你的需求,把像Apple那种有重复且含Approved的水果所有行都排除掉,只留下符合条件的唯一行啦。
内容的提问来源于stack exchange,提问作者nullptr
相关产品推荐
相关产品推荐

