子查詢(Subquery)是指出現在另一條 SQL 語句內部的 SELECT 語句,常用於將多步驟查詢合併為單條語句。
-- 客戶表
CREATE TABLE customers (
cust_id INT PRIMARY KEY,
cust_name VARCHAR(10),
cust_tel VARCHAR(10)
);
-- 訂單表
CREATE TABLE orders (
order_id INT PRIMARY KEY,
cust_id INT,
order_time DATETIME,
FOREIGN KEY (cust_id) REFERENCES customers(cust_id)
);
-- 訂單明細表
CREATE TABLE orderitems (
item_id INT PRIMARY KEY,
order_id INT,
content VARCHAR(20),
quantity INT,
FOREIGN KEY (order_id) REFERENCES orders(order_id)
);
測試數據截圖:



傳統分步查詢:
SELECT order_id FROM orderitems WHERE content = 'apple';SELECT cust_id FROM orders WHERE order_id IN (...);SELECT cust_name, cust_tel FROM customers WHERE cust_id IN (...);-- 步驟 1+2 合併
SELECT cust_id FROM orders
WHERE order_id IN (
SELECT order_id FROM orderitems WHERE content = 'apple'
);
-- 完整三層嵌套
SELECT cust_name, cust_tel FROM customers
WHERE cust_id IN (
SELECT cust_id FROM orders
WHERE order_id IN (
SELECT order_id FROM orderitems WHERE content = 'apple'
)
);



關鍵規則:
1. 子查詢SELECT列數必須與外層IN/=比較的列數一致
2. 嵌套層數理論無限制,但效能考量建議 ≤ 3 層
3. 格式化縮進、分行寫法大幅提升可讀性
需求:顯示每位客戶的訂單總數
-- 單客戶查詢
SELECT COUNT(*) AS order_total FROM orders WHERE cust_id = 1;
-- 作為計算欄位
SELECT cust_name, cust_tel,
(SELECT COUNT(*) FROM orders WHERE orders.cust_id = customers.cust_id) AS order_total
FROM customers;


相關子查詢:內層引用外層表別名(
orders.cust_id = customers.cust_id),外層每行都會執行一次內層查詢。大數據量時建議改用JOIN + GROUP BY或衍生表優化。
IN 子查詢返回單列,EXISTS 不關心列JOIN 替代 IN 子查詢EXISTS 通常比 IN 快(可短路)SELECT 列表放相關子查詢(N+1 問題)WITH CTE (MySQL 8.0+) 拆解複雜邏輯