我到現在還記得那個下午。
坐在咖啡廳裡,筆電開著,專案截止日在即。我需要從資料庫撈一些客戶資料——很簡單的查詢,沒什麼複雜的。我仔細檢查了資料表名稱、確認了欄位名稱、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 分鐘除錯清單
當查詢沒結果時,按這個順序檢查:
- ✅ NULL 檢查 - 用了
= NULL嗎?改成IS NULL - ✅ 字串 - 引號?大小寫?空白字元?
- ✅ 邏輯 - AND/OR 混用有加括號嗎?
- ✅ 拼字 - 資料表和欄位名稱對嗎?
- ✅ 日期 - 日期格式和比較方式對嗎?
- ✅ 資料 - 資料真的存在嗎?
- ✅ 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 個!)
.
.
.
答案:
- 缺引號:應該是
'Electronics' - 缺括號:AND/OR 混用要加括號
= NULL應該是IS NULL- 日期比較可能需要範圍(如果是 timestamp)
你答對幾個?
寫在最後
學 SQL 就是不斷踩坑、解決問題的過程。這 7 個除錯點,每一個我都踩過(有些還踩了不只一次)。
現在分享給你,就是希望你能少走彎路。把這份清單存起來,下次遇到問題時拿出來用。相信我,你會用到的。
如果這篇文章幫到你了,歡迎:
- 👏 拍手支持
- 💬 留言分享你的除錯經驗
- 📤 分享給正在學 SQL 的朋友
我們一起進步!
延伸閱讀
關於作者
我是 Leon(亮之),一個熱愛分享技術的工程師。這個系列記錄了我學習 SQL 的心路歷程,包括踩過的坑、學到的教訓,以及實用的技巧。
如果喜歡這類文章,歡迎追蹤我的方格子,我會持續分享更多實用的程式開發心得!
追蹤我,一起成長 🚀
互動時間
你學 SQL 時遇過最難 debug 的「沒結果」問題是什麼?在底下留言分享你的故事,說不定能幫助到其他讀者!
我會在留言區回覆大家 😊














