資料庫基礎
想從客戶表格(客戶編號, 姓名)與訂單表格(訂單編號, 客戶編號, 金額)中,求出從未下過訂單之客戶的姓名。正確的SQL敘述是下列何者?
- ASELECT 姓名 FROM 客戶 WHERE EXISTS (SELECT * FROM 訂單 WHERE 訂單.客戶編號 = 客戶.客戶編號)
- BSELECT 姓名 FROM 客戶 WHERE NOT EXISTS (SELECT * FROM 訂單)
- CSELECT 姓名 FROM 客戶 WHERE NOT EXISTS (SELECT * FROM 訂單 WHERE 訂單.客戶編號 = 客戶.客戶編號)
查看答案與解析
正確答案:C. SELECT 姓名 FROM 客戶 WHERE NOT EXISTS (SELECT * FROM 訂單 WHERE 訂單.客戶編號 = 客戶.客戶編號)
EXISTS是一種述詞:括號中的子查詢只要傳回一筆以上結果就為真,一筆都沒有就為假;NOT EXISTS則相反。在子查詢中像 訂單.客戶編號 = 客戶.客戶編號 這樣使用外層表格的欄位,就成為相關子查詢,會對外層客戶表格的每筆資料列,檢查該客戶是否有訂單。與NOT EXISTS組合後,只會留下一筆訂單都沒有的客戶。若改用EXISTS,求出的反而是下過訂單的客戶。若子查詢中沒有與客戶對應的條件,只要訂單表格有一筆資料列,子查詢就一定會傳回資料列,NOT EXISTS永遠為假,結果為0筆。以LEFT OUTER JOIN連結後,選出訂單端欄位為NULL的資料列,也能得到相同的結果。
- A. 因為使用EXISTS,求出的是下過訂單的客戶。
- B. 子查詢沒有針對每位客戶的條件,只要訂單表格有一筆資料列,結果就是0筆。
- C. 正確。對每位客戶檢查有無訂單,只留下一筆訂單都沒有的客戶。