為什麼你的 SQL 查詢沒有結果?完整除錯指南(5 分鐘清單)

更新 發佈閱讀 13 分鐘

我到現在還記得那個下午。

坐在咖啡廳裡,筆電開著,專案截止日在即。我需要從資料庫撈一些客戶資料——很簡單的查詢,沒什麼複雜的。我仔細檢查了資料表名稱、確認了欄位名稱、WHERE 條件看起來也對。

信心滿滿地按下執行鍵。

0 rows returned.

如果你也遇過這種狀況——明明知道資料存在、明明查詢語法看起來沒問題,卻一直拿到零筆結果——這篇文章就是為你而寫。

今天我要分享一套系統化的除錯清單,這是我從無數次 debug 中學到的經驗。這 7 個檢查點能解決 99% 的「沒結果」問題,而且你只需要 5 分鐘就能跑完全部。

準備好了嗎?我們開始。


原因 1:NULL 比較問題(最常見!)

如果要我猜 SQL 查詢沒結果的最常見原因,絕對是這個:

SELECT * FROM employees
WHERE manager_id = NULL;

這個查詢看起來很合理對吧?你想找沒有主管的員工。但這個查詢永遠不會回傳任何結果,就算你的資料表裡有一半員工的 manager_id 是 NULL 也一樣。

為什麼會這樣?

因為在 SQL 的世界裡,NULL 不是「沒有東西」,而是代表「未知」。你無法用等號去比較未知的東西。

就好比問:「這個神秘盒子等於那個神秘盒子嗎?」答案不是對或錯,而是「我不知道」。

正確寫法

SELECT * FROM employees
WHERE manager_id IS NULL;

記住:

  • 檢查空值用 IS NULL
  • 檢查非空值用 IS NOT NULL
  • 永遠不要用 = NULL<> NULL

這一個修正,就能解決大概 40% 的「沒結果」問題。


原因 2:字串比較的陷阱

你要找一個客戶:

SELECT * FROM customers
WHERE name = 'john smith';

沒結果。但你明明剛才在資料表裡看到「John Smith」啊!

三個可能的問題

1. 大小寫敏感

根據資料庫的設定,'leon wong' 可能不會符合 'Leon Wong'

-- 轉成小寫比較
WHERE LOWER(name) = LOWER('leon wong')

-- PostgreSQL 的不分大小寫比較
WHERE name ILIKE 'leon wong'

2. 隱藏的空白字元

資料庫裡存的是 'Leon Wong '(後面有空格),但你搜尋的是 'Leon Wong'

-- 去除空白
WHERE TRIM(name) = 'Leon Wong'

-- 或用模糊比對
WHERE name LIKE '%Leon Wong%'

3. 忘記加引號

-- 錯誤 - SQL 以為 Electronics 是欄位名稱
WHERE category = Electronics

-- 正確
WHERE category = 'Electronics'

快速除錯技巧

SELECT DISTINCT column_name FROM table;

這會列出所有實際存在的值,你就能精確比對。


原因 3:AND 和 OR 的優先順序問題

這個很陰險,因為查詢不會報錯——只是給你錯誤的結果(或零筆結果)。

SELECT * FROM products
WHERE category = 'Electronics'
OR category = 'Computers'
AND price < 500;

你的想法:「找出 500 元以下的電子產品或電腦」

SQL 的理解:「找出所有電子產品(不管價格)或是 500 元以下的電腦」

因為 AND 的優先順序比 OR 高,就像數學的先乘除後加減一樣。

永遠用括號!

WHERE (category = 'Electronics' OR category = 'Computers')
AND price < 500;

不要相信自己記得住優先順序。用括號。每一次。你的未來自己會感謝你。


原因 4:資料表或欄位名稱打錯

有時候答案非常簡單(而且尷尬):

SELECT * FROM costumers  -- 應該是 "customers"
WHERE first_name = 'Leon' -- 可能是 "firstname""fname"

快速檢查

-- 查看所有資料表
SHOW TABLES; -- MySQL
\\dt -- PostgreSQL

-- 查看欄位名稱
DESCRIBE customers; -- MySQL
\\d customers -- PostgreSQL

也要注意 schema 的問題——你可能在查 staging.users 但其實資料在 public.users


原因 5:日期時間比較的坑

你想找今天的訂單:

SELECT * FROM orders
WHERE order_date = '2025-10-19';

沒結果。但你今天早上才下了一筆訂單啊!

問題在哪?

order_date 欄位是 DATETIME 而不是 DATE

  • 儲存的值:2025-10-19 14:23:45
  • 你搜尋的:2025-10-19(被解讀為 2025-10-19 00:00:00
  • 當然不會符合!

解決方法

-- 方法 1:使用範圍
WHERE order_date >= '2025-10-19'
AND order_date < '2025-10-20'

-- 方法 2:只取日期部分
WHERE DATE(order_date) = '2025-10-19'

也要注意時區問題——資料庫可能儲存 UTC 時間,但你用的是本地時間。


原因 6:資料根本不存在

在深入 debug 之前,先確認資料真的存在:

-- 資料表有資料嗎?
SELECT COUNT(*) FROM employees;

-- 這個值存在嗎?
SELECT DISTINCT department FROM employees;

可能的狀況:

  • 資料被刪除了
  • 你在測試資料庫,裡面是空的
  • 值改了('Sales' 變成 'Sales Department')
  • 你要找的東西從來沒存在過

逐步測試技巧

SELECT * FROM employees
WHERE department = 'Sales'
-- AND hire_date > '2020-01-01'
-- AND salary > 50000;

一次加一個條件,看哪個條件把結果弄沒了。


原因 7:JOIN 的問題

SELECT e.name d.department_name
FROM employees e
JOIN departments d ON e.department_id = d.id;

兩個資料表都有資料,但查詢結果是空的。

為什麼?

INNER JOIN 只會回傳兩邊都有符合的資料。如果員工的 department_id = 5,但 departments 表裡沒有 id = 5,這個員工就會消失。

除錯方法

-- 檢查孤兒記錄
SELECT * FROM employees
WHERE department_id NOT IN (SELECT id FROM departments);

--LEFT JOIN 看缺少什麼
SELECT e.name, d.department_name
FROM employees e
LEFT JOIN departments d ON e.department_id = d.id;
-- department_name 是 NULL 的就是沒配對到的

你的 5 分鐘除錯清單

當查詢沒結果時,按這個順序檢查:

  1. NULL 檢查 - 用了 = NULL 嗎?改成 IS NULL
  2. 字串 - 引號?大小寫?空白字元?
  3. 邏輯 - AND/OR 混用有加括號嗎?
  4. 拼字 - 資料表和欄位名稱對嗎?
  5. 日期 - 日期格式和比較方式對嗎?
  6. 資料 - 資料真的存在嗎?
  7. JOIN - 在 JOIN 時丟失資料了嗎?

進階技巧:診斷欄位

SELECT 
name,
department,
department = 'Sales' AS dept_check,
hire_date,
hire_date > '2020-01-01' AS date_check
FROM employees
WHERE department = 'Sales'
AND hire_date > '2020-01-01';

這樣可以看出哪個條件出了問題。


快速修復技巧

1. 萬用健全性檢查

SELECT * FROM table_name LIMIT 10;

移除所有篩選條件——資料表有資料嗎?

2. 精確比對失敗時用模糊比對

WHERE name LIKE '%Leon%'

看看部分比對有沒有效。

3. 簡化後再逐步加回

WHERE condition1  -- 這個有用嗎?
-- 然後加:WHERE condition1 AND condition2

4. 看實際的值

SELECT DISTINCT column_name FROM table;

看看真正存在什麼值。


我希望有人早點告訴我的事

拿到零筆結果不是失敗——是回饋。

資料庫在告訴你:「我照你說的地方、用你給的條件去找了,什麼都沒有。」現在你知道該往哪裡看了。

大部分的「沒結果」問題都落在這 7 個類別裡。你可以在 5 分鐘內全部檢查完。練習得越多,就能越快找到問題。

下次看到 0 rows returned 時,深呼吸一口氣,拿出這份清單,系統性地一項一項檢查。不要亂跳——照順序來。

你會找到的。


練習題

來找找這個查詢有什麼問題:

SELECT * FROM products
WHERE category = Electronics
OR price < 100
AND in_stock = NULL
AND created_date = '2025-10-19';

能找到幾個錯誤?(至少有 4 個!)

.

.

.

答案:

  1. 缺引號:應該是 'Electronics'
  2. 缺括號:AND/OR 混用要加括號
  3. = NULL 應該是 IS NULL
  4. 日期比較可能需要範圍(如果是 timestamp)

你答對幾個?


寫在最後

學 SQL 就是不斷踩坑、解決問題的過程。這 7 個除錯點,每一個我都踩過(有些還踩了不只一次)。

現在分享給你,就是希望你能少走彎路。把這份清單存起來,下次遇到問題時拿出來用。相信我,你會用到的。

如果這篇文章幫到你了,歡迎:

  • 👏 拍手支持
  • 💬 留言分享你的除錯經驗
  • 📤 分享給正在學 SQL 的朋友

我們一起進步!


延伸閱讀


關於作者

我是 Leon亮之),一個熱愛分享技術的工程師。這個系列記錄了我學習 SQL 的心路歷程,包括踩過的坑、學到的教訓,以及實用的技巧。

如果喜歡這類文章,歡迎追蹤我的方格子,我會持續分享更多實用的程式開發心得!

追蹤我,一起成長 🚀


互動時間

你學 SQL 時遇過最難 debug 的「沒結果」問題是什麼?在底下留言分享你的故事,說不定能幫助到其他讀者!

我會在留言區回覆大家 😊

留言
avatar-img
留言分享你的想法!
avatar-img
Leon Wong 282
2會員
8內容數
Hi,我是 Leon Wong(亮之)——電腦科學與開發愛好者,也是 Notion 重度使用者。如果你想更高效地學習與創作,這裡會是你的實用資源。
Leon Wong 282的其他內容
2025/10/20
全面掌握 SQL WHERE 子句的篩選技巧:等於/不等於、大小比較、BETWEEN、IN、LIKE(%/_)、AND/OR/NOT 的正確組合與常見坑(優先順序、引號、大小寫、索引效能)、NULL 的正確處理,以及 WHERE 與 HAVING 的差異。讓新手到進階都能寫出可靠的查詢。
2025/10/20
全面掌握 SQL WHERE 子句的篩選技巧:等於/不等於、大小比較、BETWEEN、IN、LIKE(%/_)、AND/OR/NOT 的正確組合與常見坑(優先順序、引號、大小寫、索引效能)、NULL 的正確處理,以及 WHERE 與 HAVING 的差異。讓新手到進階都能寫出可靠的查詢。
2025/10/19
SQL 是程式開發人員必學的工具,但新手常常會犯一些常見的錯誤,例如使用 `= NULL` 而不是 `IS NULL`,或是忘記為字串加上引號。本文將整理 7 個最常見的 SQL 錯誤,分析錯誤原因並提供正確的解法,幫助你避免走冤枉路,大幅提升開發效率。
2025/10/19
SQL 是程式開發人員必學的工具,但新手常常會犯一些常見的錯誤,例如使用 `= NULL` 而不是 `IS NULL`,或是忘記為字串加上引號。本文將整理 7 個最常見的 SQL 錯誤,分析錯誤原因並提供正確的解法,幫助你避免走冤枉路,大幅提升開發效率。
2025/10/16
上週,我花了 20 分鐘在 Word 裡排版一份文件。標題調得漂漂亮亮,項目符號排列整齊,字體大小都恰到好處。按下傳送鍵,信心滿滿地等待同事回覆。 結果呢? 「欸,你傳的檔案格式跑掉了耶。」同事傳來訊息,還附上一張慘不忍睹的截圖——我的精心排版完全崩潰,看起來就像綁匪的恐嚇信。 我知道你一定也
2025/10/16
上週,我花了 20 分鐘在 Word 裡排版一份文件。標題調得漂漂亮亮,項目符號排列整齊,字體大小都恰到好處。按下傳送鍵,信心滿滿地等待同事回覆。 結果呢? 「欸,你傳的檔案格式跑掉了耶。」同事傳來訊息,還附上一張慘不忍睹的截圖——我的精心排版完全崩潰,看起來就像綁匪的恐嚇信。 我知道你一定也
看更多
你可能也想看
Thumbnail
還在煩惱平凡日常該如何增添一點小驚喜嗎?全家便利商店這次聯手超萌的馬來貘,推出黑白配色的馬來貘雪糕,不僅外觀吸睛,層次豐富的雙層口味更是讓人一口接一口!本文將帶你探索馬來貘雪糕的多種創意吃法,從簡單的豆漿燕麥碗、藍莓果昔,到大人系的奇亞籽布丁下午茶,讓可愛的馬來貘陪你度過每一餐,增添生活中的小確幸!
Thumbnail
還在煩惱平凡日常該如何增添一點小驚喜嗎?全家便利商店這次聯手超萌的馬來貘,推出黑白配色的馬來貘雪糕,不僅外觀吸睛,層次豐富的雙層口味更是讓人一口接一口!本文將帶你探索馬來貘雪糕的多種創意吃法,從簡單的豆漿燕麥碗、藍莓果昔,到大人系的奇亞籽布丁下午茶,讓可愛的馬來貘陪你度過每一餐,增添生活中的小確幸!
Thumbnail
已經存在在table裡面的那些record做更新。 ※ 語法 UPDATE [LOW_PRIORITY] [IGNORE] table_name SET column_name1 = expr1, column_name2 = expr2, … [WHERE
Thumbnail
已經存在在table裡面的那些record做更新。 ※ 語法 UPDATE [LOW_PRIORITY] [IGNORE] table_name SET column_name1 = expr1, column_name2 = expr2, … [WHERE
Thumbnail
※ 為什麼需要 Subquery? 當⼀個任務需要多個 Query 完成任務,可以使⽤ Subquery 把多個 Query 合併成⼀個 Query。 當我們在進行SQL查詢時,每次查詢都需要在Web Server和資料庫之間來回傳遞資料。這個過程會產生網路延遲,特別是當兩者之間的物理距離較遠時
Thumbnail
※ 為什麼需要 Subquery? 當⼀個任務需要多個 Query 完成任務,可以使⽤ Subquery 把多個 Query 合併成⼀個 Query。 當我們在進行SQL查詢時,每次查詢都需要在Web Server和資料庫之間來回傳遞資料。這個過程會產生網路延遲,特別是當兩者之間的物理距離較遠時
Thumbnail
※ 什麼是WHERE? 使用 WHERE來設定條件,可以幫助我們縮小查詢結果的範圍,取得想要的結果。 ※ 語法: ※ 解析順序: From:先看是哪一張table→table裡面符合Where指定條件的record→再看Select指定的是那些欄位→再根據那個欄位進行排序。 ※ 使⽤⽅
Thumbnail
※ 什麼是WHERE? 使用 WHERE來設定條件,可以幫助我們縮小查詢結果的範圍,取得想要的結果。 ※ 語法: ※ 解析順序: From:先看是哪一張table→table裡面符合Where指定條件的record→再看Select指定的是那些欄位→再根據那個欄位進行排序。 ※ 使⽤⽅
Thumbnail
這篇文章主要是介紹了SQL查詢效能調校的方法,針對索引最佳化做了整理和分享,並提供了一些注意事項和建議。
Thumbnail
這篇文章主要是介紹了SQL查詢效能調校的方法,針對索引最佳化做了整理和分享,並提供了一些注意事項和建議。
Thumbnail
每日自動檢查資料庫運作所產生的訊息,若發現有錯誤,自動寄出警告信給擔當人員
Thumbnail
每日自動檢查資料庫運作所產生的訊息,若發現有錯誤,自動寄出警告信給擔當人員
Thumbnail
資料庫之備份工作大都是自動執行,但是執行結果是否成功,需要安排人員去檢查,有時疏忽忘記確認作業,致備份工作失敗仍不知道,等到有一天需要回復舊有資料的場合時,才發現找不到過去某段期間的備份資料,造成無法彌補之後果。   2.    改善: 2.1 設計一執行檔,功能為打開備
Thumbnail
資料庫之備份工作大都是自動執行,但是執行結果是否成功,需要安排人員去檢查,有時疏忽忘記確認作業,致備份工作失敗仍不知道,等到有一天需要回復舊有資料的場合時,才發現找不到過去某段期間的備份資料,造成無法彌補之後果。   2.    改善: 2.1 設計一執行檔,功能為打開備
追蹤感興趣的內容從 Google News 追蹤更多 vocus 的最新精選內容追蹤 Google News