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

SQL 三表聯查中第二表字段為空導致結果缺失:LEFT JOIN 與 COALESCE 解決方案

     編輯:程式設計綜合問答

三表關聯查詢:table1 (id1) → table2 (id2, id1, no) → table3 (no, name)。當 table2.no 為 NULL 時,INNER JOIN table3 ON t2.no = t3.no 會過濾掉這些行,導致 name 缺失。需改用外連接並處理空值。

原查詢(缺失數據)

SELECT t3.name
FROM table1 t1 (NOLOCK)
INNER JOIN table2 t2 (NOLOCK) ON t1.id1 = t2.id1
INNER JOIN table3 t3 (NOLOCK) ON t2.no = t3.no;

方案一:LEFT JOIN 保留主表記錄(推薦)

SELECT t3.name
FROM table1 t1 (NOLOCK)
INNER JOIN table2 t2 (NOLOCK) ON t1.id1 = t2.id1
LEFT JOIN table3 t3 (NOLOCK) ON t2.no = t3.no;
  • t2.no 為 NULL 時,t3.name 返回 NULL,但 t1/t2 行保留。
  • 若需顯示默認值:COALESCE(t3.name, '無名稱') AS name。

方案二:將 NULL 轉為空字符串再 JOIN(不推薦,性能差)

-- SQL Server
INNER JOIN table3 t3 (NOLOCK) ON t2.no = ISNULL(t3.no, '')

-- MySQL / PostgreSQL
INNER JOIN table3 t3 ON t2.no = COALESCE(t3.no, '')
  • 利用索引失效(函數作用於列),大數據量下查詢極慢。
  • 語義上將 NULL 強行匹配空字符串,可能產生錯誤關聯。

方案三:子查詢/APPLY 獲取名稱(靈活)

SELECT t1.id1,
       (SELECT t3.name FROM table3 t3 WHERE t3.no = t2.no) AS name
FROM table1 t1
INNER JOIN table2 t2 ON t1.id1 = t2.id1;
  • 子查詢返回 NULL 時不影響主查詢行數。
  • 適用於「一對一/多」輔助屬性查詢。

最佳實踐建議

  1. **優先使用 LEFT JOIN**,語義清晰、利用索引、標準 SQL。
  2. 在 SELECT 列表用 COALESCE/ISNULL 給業務友好默認值。
  3. 檢查 table2.no 是否應設置 NOT NULL 或外鍵約束,從源頭治理數據質量。
  4. NOLOCK (READ UNCOMMITTED) 可能讀到臟數據,核心業務慎用。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved