子查詢是構建複雜邏輯的核心工具。本文按出現位置(FROM/WHERE/EXISTS)與返回結果形態(標量/列/行/表)雙維度分類,配合「先寫外層目標,再填內層條件」的通用思維模型,逐一拆解 5 大類型實戰用法。
適用位置:WHERE 比較運算符(=, >, <, >=, <=, <>)、SELECT 列表、ORDER BY 等。
-- 目標:教室名 SELECT room FROM class WHERE id = (SELECT c_id FROM stu WHERE s_name = 'zhangsan');


關鍵:子查詢必須只返回一行一列,否則報錯 Subquery returns more than 1 row。
適用操作符:IN、NOT IN、ANY、ALL、EXISTS(轉換)。
SELECT * FROM stu
WHERE c_id IN (SELECT id FROM class WHERE c_name IN ('php', 'ios'));

適用場景:多列聯合比較,使用元組構造器 (col1, col2) = (val1, val2)。
SELECT * FROM stu WHERE (age, sex) = (SELECT MAX(age), sex FROM stu WHERE sex = 1);

位置:FROM 子句後,作為臨時數據源參與 Join/聚合。
SELECT s.*
FROM stu s
JOIN (
SELECT c_id, MAX(age) AS max_age
FROM stu
GROUP BY c_id
) t ON s.c_id = t.c_id AND s.age = t.max_age;


MySQL 8.0+ 推薦:使用 CTE (WITH t AS (...) SELECT ...) 替代 FROM 子查詢,可讀性更強、可復用。
特點:不關心返回具體值,只關心是否存在至少一行。內層常用 SELECT 1 或 SELECT *,優化器可短路優化。
SELECT * FROM class c WHERE c.c_name = 'php' AND EXISTS (SELECT 1 FROM stu s WHERE s.c_id = c.id);

IN(或 JOIN)更優。EXISTS 更優(外層驅動,內層索引查找)。IN 做了半連接優化,大多數場景性能接近,優先寫語義清晰的。AS t,否則報錯 Every derived table must have its own alias。NOT EXISTS 或 LEFT JOIN ... IS NULL。掌握 5 大類型的適用邊界與思維模型,子查詢將成為你處理複雜業務邏輯的得力工具,而非性能殺手。