SQL 子查詢中,SELECT 列表中的標量子查詢只需引用一張表,外層主查詢的表不必出現在子查詢 FROM 中。本文通過具體例子解析執行邏輯與等價 JOIN 寫法。
SELECT
c.cust_name,
c.cust_state,
(SELECT COUNT(*) FROM orders WHERE cust_id = c.cust_id) AS order_count
FROM customers c
ORDER BY c.cust_name;
疑問:子查詢 `FROM orders` 中為何沒有 `customers` 表?
假設 customers 有 3 行:
SELECT
c.cust_name,
c.cust_state,
COALESCE(o.order_cnt, 0) AS order_count
FROM customers c
LEFT JOIN (
SELECT cust_id, COUNT(*) AS order_cnt
FROM orders
GROUP BY cust_id
) o ON c.cust_id = o.cust_id
ORDER BY c.cust_name;
| 維度 | 相關子查詢 | LEFT JOIN + 子查詢 |
|---|---|---|
| 可讀性 | 直觀,邏輯集中 | 稍顯分散 |
| 性能 | 大表時較慢 (N 次掃描) | 通常更優 (1 次掃描 + Hash Join) |
| 適用場景 | 外層行數少、無索引 | 常規報表、大數據量 |
| 空值處理 | 自動返回 NULL | 需 COALESCE/ISNULL |
子查詢 `FROM` 中無外層表是正確語法。相關子查詢通過外層列引用實現關聯,而非在 FROM 中列出表。理解「逐行代入執行」模型是掌握相關子查詢的關鍵。