2015-11-21 48 views
1

我想要提供每個部件的供應商的SIDS。我無法理解本書給出的查詢答案。SQL嵌套不存在瞭解

Suppliers(sid: integer, sname: string, address: string) 
Parts(pid: integer, pname: string, color: string) 
Catalog(sid: integer, pid: integer, cost: real) 

假設給定了一個數據庫,如下所示:

表:零件

PID 
P1 
P2 
P3 

表:目錄

SID PID 
S1 P1 
S1 P2 
S1 P3 
S2 P1 

它應該輸出S1,但我相信用給定的查詢,它將輸出S1和S2。最後一個嵌套查詢不會滿足SID = 2嗎?因爲如果C1.sid = S2和C.sid = S2並且C1.pid = P1並且P.pid = P1,那麼它將滿足查詢。

這本書的答案給出如下: SQL翻譯:「C.Sid爲不存在未通過C.Sid提供的部分」

SELECT C.sid 
FROM Catalog C 
WHERE NOT EXISTS (SELECT P.pid 
        FROM Parts P 
        WHERE NOT EXISTS (SELECT C1.sid 
            FROM Catalog C1 
            WHERE C1.sid = C.sid 
            AND C1.pid = P.pid) 
       ) 

回答

1

一個簡單的'矛盾證明'將證明查詢永遠不會返回S2。

對於查詢返回S2,第一個NOT EXISTS將要求Parts上的子查詢產生零行。這當然不是這種情況,因爲該特定的子查詢返回了不由S2提供的所有部分(即P2和P3)。

0

薩姆,你給了自己答案。

查詢選擇結果中不需要的sid(不存在的地方)。

因此,查詢選擇S2(不是兩個),並且因爲您選擇的所有sid不在其上,所以結果爲S1。

簡單的話;你正在用sid創建一個你不想要的最終結果列表。

1

你應該閱讀查詢爲:

給我這不存在有沒有相應的產品目錄中abovemensioned供應商這樣的零部件供應商。你應該在這裏從上到下閱讀查詢。想象一下Catalogs表上的循環。取第一行(S1,P1)。爲Parts做一個內部循環,並檢查該部分是否存在S1。它存在。好。取第二部分。它存在。取第三部分。它存在。因此,對於第一行,不存在第一行供應商的目錄中不存在的此類零件。取第二行(S1,P2)等...