SQL中的關係除法實現方式

今天學習到了如何通過NOT EXISTS來實現SQL中的關係除法,記錄一下以備日後溫習。

已經瞭解到,SQL現成的集合運算符有:UNION(並集)、EXCEPT(差集)、INTERSECT(交集)、CROSS JOIN(笛卡兒積),但關係除法是沒有現成函數的。

由於下面會用到,所以首先熟悉一下 EXISTS 的作用和用法:

例如下面的代碼實現的功能是找出在Table1、Table2中同時存在的全部id所對應的行

SELECT * FROM Table1 WHERE EXISTS( SELECT 1 FROM Table2 WHERE Table2.id=Table1.id) ;
/*內查詢中select後面的內容可以任意設定,哪怕NULL都OK,不影響結果,
因爲EXISTS函數的內查詢中返回的是布爾值True或False,
對應着查詢結果存在與否,與結果的實際內容無關*/

結果等同於IN語句

SELECT * FROM Table1 WHERE id IN(SELECTid FROM Table2);

接下來正式進入關係除法的演示部分,我們使用兩張表作爲示例用表。
Skill表:

-----
Skill
------
Oracle
UNIX
Java

EmpSkills表:

emp     skill
--------------
相田    Oracle
相田    UNIX
相田    Java
相田    C#
神崎    Oracle
神崎    UNIX
神崎    Java
平井    UNIX
平井    Oracle
平井    PHP
平井    Perl
平井    C++
若田部  Perl
渡來    Oracle

以下這個問題就是除法的典型應用:

“從該表中選取出掌握了Skills表中所有3個領域的技術的員工”

方法一:

SELECT DISTINCT emp
FROM EmpSkills ES1
WHERE NOT EXISTS
(SELECT skill
FROM Skills
EXCEPT
SELECT skill
FROM EmpSkills ES2
WHERE ES1.emp = ES2.emp);--原書作者有筆誤

這樣我們就得到了包含相田和神崎2 人的結果。

emp
------
神崎
相田

通過另一種方法,可以實現同樣的結果。

方法二:

SELECT emp 
FROM EmpSkills
WHERE skill in (SELECT skill FROM Skills)
GROUP BY emp
HAVING COUNT(DISTINCT skill)=(SELECT COUNT(skill) FROM Skills);
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章