在Microsoft SQL Server 2014中筛选不包含特定值的分组
筛选不包含特定值的分组(SQL Server 2014)
结合你的表结构和需求,我来给你梳理几种实用的实现方案——这里默认你是要按员工(EMPID)分组,找出分组内不包含某个特定机型(AID)认证的员工,你可以根据实际需要替换特定值。
先明确你的表结构:
EMPLOYEES表
EMPID | FIRSTNAME 1 | JOHNNY 2 | DWAYNE 3 | TOM 4 | CHRISTIAN 5 | JACK 6 | BRAD 7 | ADAM 8 | MATT 9 | WILL 10 | JIM
AIRCRAFTS表
AID | NAME 1 | BOEING 1 2 | BOEING 2 3 | BOEING 3 4 | BOEING 4 5 | AIRBUS 1 6 | AIRBUS 2 7 | LEARJET 8 | DOUGLAS 9 | JUMBO 10 | ILYUSHIN
CERTIFIED表
EMPID | AID 1 | 1 1 | 2 1 | 3 1 | 4 4 | 2 4 | 3 7 | 1 7 | 2 7 | 5 7 | 6 8 | 7 8 | 8 8 | 9 2 | 10 2 | 1 2 | 9 3 | 10 5 | 8 5 | 9
方案1:使用NOT EXISTS(推荐,性能最优)
这种方法逻辑最直接,SQL Server对NOT EXISTS的查询优化也很到位,适合大多数场景:
SELECT e.EMPID, e.FIRSTNAME FROM EMPLOYEES e WHERE NOT EXISTS ( SELECT 1 FROM CERTIFIED c WHERE c.EMPID = e.EMPID AND c.AID = 10 -- 替换成你要排除的特定AID值 ) ORDER BY e.EMPID;
结果说明:运行后会返回EMPID为1、4、5、6、7、8、9、10的员工——这些人都没有AID=10的机型认证。
方案2:使用LEFT JOIN + IS NULL
通过左连接关联员工和认证表,筛选出关联后目标AID字段为NULL的记录(即没有对应认证的员工):
SELECT DISTINCT e.EMPID, e.FIRSTNAME FROM EMPLOYEES e LEFT JOIN CERTIFIED c ON e.EMPID = c.EMPID AND c.AID = 10 WHERE c.AID IS NULL ORDER BY e.EMPID;
注意要加DISTINCT,避免单个员工多条认证记录导致的重复结果。
方案3:使用GROUP BY + HAVING
按员工分组后,检查分组内是否完全不包含目标AID值:
-- 仅包含有认证记录的员工 SELECT e.EMPID, e.FIRSTNAME FROM EMPLOYEES e JOIN CERTIFIED c ON e.EMPID = c.EMPID GROUP BY e.EMPID, e.FIRSTNAME HAVING SUM(CASE WHEN c.AID = 10 THEN 1 ELSE 0 END) = 0 ORDER BY e.EMPID;
如果要包含没有任何认证记录的员工(比如EMPID=6、9、10),需要改成左连接并调整条件:
SELECT e.EMPID, e.FIRSTNAME FROM EMPLOYEES e LEFT JOIN CERTIFIED c ON e.EMPID = c.EMPID GROUP BY e.EMPID, e.FIRSTNAME HAVING SUM(CASE WHEN c.AID = 10 THEN 1 ELSE 0 END) = 0 ORDER BY e.EMPID;
扩展:筛选不包含多个特定值的分组
如果要找既没有AID=10也没有AID=9认证的员工,只需调整条件即可:
- 用
NOT EXISTS实现:
SELECT e.EMPID, e.FIRSTNAME FROM EMPLOYEES e WHERE NOT EXISTS ( SELECT 1 FROM CERTIFIED c WHERE c.EMPID = e.EMPID AND c.AID IN (9,10) -- 多个要排除的值 ) ORDER BY e.EMPID;
- 用
GROUP BY + HAVING实现:
SELECT e.EMPID, e.FIRSTNAME FROM EMPLOYEES e LEFT JOIN CERTIFIED c ON e.EMPID = c.EMPID GROUP BY e.EMPID, e.FIRSTNAME HAVING SUM(CASE WHEN c.AID IN (9,10) THEN 1 ELSE 0 END) = 0 ORDER BY e.EMPID;
内容的提问来源于stack exchange,提问作者Laximas
相关产品推荐
相关产品推荐

