子查詢按返回結果集結構分類,列子查詢 返回「N 行 1 列」,行子查詢 返回「1 行 N 列」。兩者適用場景與操作符截然不同,本文詳解核心用法與陷阱。
列子查詢常用於 WHERE column IN (subquery) 等場景。因返回多行單列,不能直接使用 = > < 等標量比較運算符,需配合集合操作符:
= ANY,判斷值是否在結果集中。> ANY),只要與子查詢任一值比較為 TRUE 則返回 TRUE。ANY 別名,用法相同。> ALL),需與子查詢所有值比較均為 TRUE 才返回 TRUE。表 table1(s1):2, 10;表 table2(s2):5, 12, 20。
SELECT s1 FROM table1 WHERE s1 > ANY (SELECT s2 FROM table2)
子查詢返回 5,12,20。s1=10 大於 5,滿足條件,故返回 10。
特殊情況:子查詢結果為空表 → ANY 為 FALSE;結果含 NULL → ANY 為 UNKNOWN。
SELECT s1 FROM table1 WHERE s1 > ALL (SELECT s2 FROM table2)
需 s1 大於 5,12,20 所有值,無滿足行,返回空集。
NOT IN 等價於 <> ALL。
特殊情況:空表 → ALL 為 TRUE;結果含 NULL → ALL 為 UNKNOWN。
行子查詢返回單行多列,常配合 行構造符 (val1, val2...) 或 ROW(val1, val2...) 進行整行比較。
SELECT * FROM table1 WHERE (1,2) = (SELECT column1, column2 FROM table2)
要求子查詢保證返回單行,若 column1=1 且 column2=2 則匹配成功。
表 article(title, content, uid)、blog(title, content, uid)。查詢 article 中與 blog 某行完全一致的記錄:
SELECT * FROM article WHERE (title, content, uid) = (SELECT title, content, uid FROM blog WHERE bid=2)

逐列比對三字段,若全等則返回該行。理論上可能返回多條符合條件的記錄。