| 運算子 | 語法形式 | 子查詢需單欄? | 可接固定集合? | 典型用途 |
|---|---|---|---|---|
| IN | col IN (subquery) / col IN (v1,v2...) | 是 | 是 | 集合成員資格測試 |
| ANY / SOME | col > ANY (subquery) | 是 | 否 | 滿足任一比較 |
| ALL | col < ALL (subquery) | 是 | 否 | 滿足所有比較 |
| EXISTS | EXISTS (subquery) | 否 (可多欄) | 否 | 存在性測試 |
SELECT * FROM T_Book WHERE FYearPublished IN (2001, 2003, 2005);
SELECT * FROM T_Reader
WHERE FYearOfJoin IN (SELECT FYearPublished FROM T_Book);
需搭配比較運算子 (>, =, <, >=, <=) 放在前面。
SELECT * FROM T_Reader
WHERE FYearOfJoin = ANY (SELECT FYearPublished FROM T_Book);
-- 等價於 IN,但 ANY 可用 >, < 等
SELECT * FROM T_Book
WHERE FYearPublished > ANY (SELECT FYearOfJoin FROM T_Reader);
-- 只要大於讀者入會年份中「任一」值即符合
錯誤示範:
WHERE FYearPublished < ANY (2001,2003,2005)— ANY/SOME/ALL 不支援固定集合。
SELECT * FROM T_Book
WHERE FYearPublished < ALL (SELECT FYearOfJoin FROM T_Reader);
-- 出版年份必須小於「所有」讀者入會年份
SELECT * FROM T_Book
WHERE FYearPublished < ALL (
SELECT FYearOfJoin FROM T_Reader WHERE FProvince = 'JiangSu'
);
若子查詢無資料 (空集合),ALL 判定為 TRUE,導致外層查詢回傳所有列。此為經典 Bug 來源,使用時務必確認子查詢非空,或改寫為 NOT EXISTS / IN 配合 NOT。
IN (特別是大量資料),因為只要找到一列即停止掃描。SELECT * FROM T_Category
WHERE EXISTS (
SELECT 1 FROM T_Book
WHERE T_Book.FCategoryId = T_Category.FId
AND T_Book.FYearPublished < 1950
);
-- 找出至少有一本 1950 年前出版書籍的類別
NOT EXISTS (SELECT 1 FROM ... WHERE ... AND col >= outer.col)。> ANY 等同 > (SELECT MIN(...)),< ALL 等同 < (SELECT MIN(...)),必要時改寫為聚合函數更直觀。IN (v1,v2...) 最簡潔。