小筆記:Exists 與 Not Exists

本篇靈感來源:
SQL 達人的工作現場攻略筆記


本書提到的兩張資料表:

table: skills table: emp_skills

原題目如下:
今日欲從 emp_skills 表中,挑出會所有skills 表上技能的員工。


這邊想記錄幾個 exists 跟 not exists 語法的效果。

  • 情況一
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
SELECT
*
FROM
emp_skills AS A
WHERE
EXISTS (
SELECT
*
FROM
skills C
WHERE
EXISTS (
SELECT
*
FROM
emp_skills AS B
WHERE
(A.emp = B.emp)
AND (B.skill = C.skill) ));

效果是,找出至少會一個skills 表上技能的員工。
因此靚儀會被去除。

result

Hint: 把每個人會的技能組當成一個集合。


  • 情況二
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
SELECT
*
FROM
emp_skills AS A
WHERE
NOT EXISTS (
SELECT
*
FROM
skills C
WHERE
EXISTS (
SELECT
*
FROM
emp_skills AS B
WHERE
(A.emp = B.emp)
AND (B.skill = C.skill) ));

效果是,找出 skills 表上技能一個都不會的員工。
因此只有靚儀會被選出。

result
  • 情況三
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
SELECT
*
FROM
emp_skills AS A
WHERE
EXISTS (
SELECT
*
FROM
skills C
WHERE
NOT EXISTS (
SELECT
*
FROM
emp_skills AS B
WHERE
(A.emp = B.emp)
AND (B.skill = C.skill) ));

效果是,找出沒有全會skills 表上技能的員工。
因此銘仁、靜儀、勝朋皆會被選出。

result
  • 情況四
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
SELECT
*
FROM
emp_skills AS A
WHERE
NOT EXISTS (
SELECT
*
FROM
skills C
WHERE
NOT EXISTS (
SELECT
*
FROM
emp_skills AS B
WHERE
(A.emp = B.emp)
AND (B.skill = C.skill) ));

在理解情況三後,這邊的效果就很明顯了。
找出會所有skills 表上技能的員工。

result

最後附上原題目的 NOT EXISTS 解法。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
SELECT
DISTINCT emp
FROM
emp_skills AS A
WHERE
NOT EXISTS (
SELECT
*
FROM
skills C
WHERE
NOT EXISTS (
SELECT
*
FROM
emp_skills AS B
WHERE
(A.emp = B.emp)
AND (B.skill = C.skill) ));

即修改 SELECT 中欄位值的情況四。

result

ʕ •ᴥ•ʔ:Zero真是 SQL 大神~