首页 > 解决方案 > SQL:选择不包含特定值的组

问题描述

我使用 Microsoft SQL Server Management Studio 2014,我有这 3 个表:

雇员

EMPID | FIRSTNAME
  1   | JOHNNY
  2   | DWAYNE
  3   | TOM
  4   | CHRISTIAN
  5   | JACK
  6   | BRAD
  7   | ADAM
  8   | MATT
  9   | WILL
  10  | JIM

飞行器

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

认证

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

这个概念是有 10 名员工和 10 架飞机。CERTIFIED 表确定了哪些员工有权驾驶哪些飞机。不过,并非所有员工都是飞行员。我需要以某种方式选择所有未获得使用波音认证的飞行员。我尝试但没有奏效的内容如下:

SELECT DISTINCT FIRSTNAME
FROM EMPLOYEES
WHERE EMPID IN (SELECT EMPID
                FROM CERTIFIED
                WHERE AID NOT IN (SELECT AID FROM AIRCRAFTS WHERE NAME LIKE 'BOEING%'))

这给出了这些结果:

JACK
MATT
TOM
ADAM
DWAYNE

这是错误的,因为根据 CERTIFIED 表,ADAM 和 DWAYNE 被授权驾驶至少一架波音。

任何帮助将不胜感激,在此先感谢!

标签: sqlsql-serverdatabase

解决方案


试试这个查询...

SELECT employees.empid, Max(employees.firstname) AS FirstName 
FROM   certified 
       INNER JOIN employees ON employees.empid = certified.empid 
WHERE  certified.empid NOT IN (SELECT certified.empid 
                               FROM   certified 
                               INNER JOIN aircrafts ON aircrafts.aid = certified.aid 
                               WHERE  aircrafts.NAME LIKE 'BOEING%') 
GROUP  BY employees.empid 

演示:http ://www.sqlfiddle.com/#!18/8f26d/27/0

结果

+-------+-----------+
| EMPID | FirstName |
+-------+-----------+
|     3 | TOM       |
|     5 | JACK      |
|     8 | MATT      |
+-------+-----------+

推荐阅读