首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 程式設計綜合問答

SQL 子查詢中 FROM 子句省略表的原因解析

     編輯:程式設計綜合問答

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` 表?

核心解釋

  • 這是相關子查詢:子查詢引用了外層查詢的列 `c.cust_id`
  • 執行邏輯:對 `customers` 表的每一行,將 `c.cust_id` 值代入子查詢,在 `orders` 表中統計匹配行數
  • 子查詢只需訪問 orders 表,因為過濾條件 `cust_id = c.cust_id` 已包含外層傳入的值
  • SELECT 子查詢必須返回單值(一行一列),否則報錯

執行順序演示

假設 customers 有 3 行:

  1. 讀取 customers 第 1 行 → `c.cust_id = 1001`
  2. 執行子查詢:`SELECT COUNT(*) FROM orders WHERE cust_id = 1001` → 返回 5
  3. 結果行:`cust_name, cust_state, 5`
  4. 讀取 customers 第 2 行 → `c.cust_id = 1002` → 子查詢返回 3
  5. ... 以此類推

等價 LEFT JOIN 寫法

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

優化建議

  • 為 `orders.cust_id` 創建索引,加速子查詢過濾
  • 外層行數 > 1000 時優先考慮 JOIN 寫法
  • MySQL 8.0+ / PostgreSQL 可用 CTE (WITH) 提升可讀性

總結

子查詢 `FROM` 中無外層表是正確語法。相關子查詢通過外層列引用實現關聯,而非在 FROM 中列出表。理解「逐行代入執行」模型是掌握相關子查詢的關鍵。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved