如何查询所有记录均标记为重复的学生姓名
问题描述
现有Students表的结构和数据如下:
| Name | Duplicate |
|---|---|
| John | no |
| Stacy | no |
| Kate | yes |
| John | yes |
| Stacy | yes |
| Kate | yes |
规则说明:姓名首次出现的记录,Duplicate字段标记为no;重复出现的记录标记为yes。
需求:编写SQL查询,找出**所有记录的Duplicate均为yes**的姓名(示例中仅需返回Kate)。
尝试过的语句:
select distinct Name from Students where duplicate='yes'
但该语句返回了John、Kate、Stacy,不符合需求——因为John和Stacy都存在标记为no的记录。
解决方案
原语句的问题在于:它只筛选出了存在yes记录的姓名,但我们要的是完全没有no记录的姓名。下面提供几种可行的写法:
方法1:分组过滤(通用型,适配大部分数据库)
通过分组统计每个姓名的记录情况,直接排除掉存在no的分组:
SELECT Name FROM Students GROUP BY Name HAVING COUNT(CASE WHEN Duplicate = 'no' THEN 1 END) = 0
或者利用字符串字典序特性,写得更简洁:
SELECT Name FROM Students GROUP BY Name HAVING MIN(Duplicate) = 'yes'
解释:no的字典序比yes小,只要某个姓名存在no记录,它的MIN(Duplicate)就会是no;只有当所有记录都是yes时,最小值才是yes,以此精准筛选目标。
方法2:NOT EXISTS子查询
直接查询那些不存在对应no记录的姓名:
SELECT DISTINCT Name FROM Students s1 WHERE NOT EXISTS ( SELECT 1 FROM Students s2 WHERE s2.Name = s1.Name AND s2.Duplicate = 'no' )
逻辑简单直接:对每个姓名,检查是否存在标记为no的记录,不存在则保留。
方法3:EXCEPT差集(适用于SQL Server、PostgreSQL等支持该语法的数据库)
先取出所有姓名,再减去存在no记录的姓名,剩余的就是目标结果:
SELECT DISTINCT Name FROM Students EXCEPT SELECT DISTINCT Name FROM Students WHERE Duplicate='no'
内容的提问来源于stack exchange,提问作者Alyssa
相关产品推荐
相关产品推荐

