SQL 新手最常犯的 7 個錯誤(以及如何修正)

更新 發佈閱讀 12 分鐘

我到現在還記得,第一次寫 SQL 查詢卻得到零筆結果的那個下午。

那時我檢查了資料表名稱、確認了欄位名稱、把查詢語法看了三遍。一切看起來都對,但資料庫就是不給我結果。我坐在電腦前盯著螢幕,心裡開始懷疑:是不是資料庫壞了?還是我連接有問題?

結果問題出在哪?我寫了 WHERE manager_id = NULL,而正確的寫法應該是 WHERE manager_id IS NULL

就差一個字,我多花了一個小時 debug。

如果你正在學 SQL,遇到類似的困擾,這篇文章就是為你而寫的。因為說實話,你犯的錯誤並不是獨一無二的——每個 SQL 新手都會犯一樣的錯。包括我,包括你們公司那個資深工程師(雖然他們不會承認)。

這篇文章,我會帶你看 7 個最常見的 SQL 錯誤、為什麼會犯這些錯,以及最重要的——要怎麼修正。學會這些,你就能少花好幾個小時 debug,把時間拿去做更有意義的事。

準備好了嗎?我們開始吧。


錯誤 1:用 = NULL 而不是 IS NULL

就從害我浪費一小時的錯誤開始講起。

當你想找出資料遺失或未定義的列,直覺上會這樣寫:

SELECT * FROM employees
WHERE manager_id = NULL;

看起來很合理對吧?這段語法不會報錯,但它永遠不會回傳任何結果——就算資料表裡確實有 NULL 值也一樣。

為什麼?

因為在 SQL 的世界裡,NULL 不是「沒有東西」,而是代表**「未知」**。你無法比較兩個未知的東西。就像問「這個神秘箱子等於那個神秘箱子嗎?」答案不是對或錯,而是「我不知道」。

正確的寫法:

SELECT * FROM employees
WHERE manager_id IS NULL;

IS NULL 來檢查空值,用 IS NOT NULL 來找有值的資料:

SELECT * FROM employees
WHERE email IS NOT NULL;

更怪的是:NULL = NULL 的結果是 NULL(不是 TRUE)。在 SQL 裡,連兩個未知值都不相等。很玄吧?


錯誤 2:忘記在字串外加引號

這個錯誤很常見,因為一旦有人指出來,你會覺得「啊我怎麼會犯這種錯」。

你可能會這樣寫:

SELECT * FROM products
WHERE category = Electronics;

按下執行,然後——錯誤訊息跳出來。資料庫以為 Electronics 是一個欄位名稱,而不是文字內容「Electronics」。

永遠要用單引號包住文字:

SELECT * FROM products
WHERE category = 'Electronics';

數字不用加引號:

WHERE price > 100        -- 正確(數字)
WHERE status = 'active' -- 正確(文字)

小陷阱:不要用雙引號包文字。在標準 SQL 裡,雙引號是用來標示識別符(資料表或欄位名稱),不是用來包文字的。單引號 = 文字內容,這是鐵則。


錯誤 3:混用 AND 和 OR 卻不加括號

這個錯誤很微妙,因為你的查詢會跑,但結果可能不是你要的。

假設你想找出所有「電子產品」和「電腦」類別中,價格低於 500 元的商品:

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

看起來很清楚對吧?找出兩個類別,但只要 500 元以下的。

錯!

因為 AND 的優先順序比 OR 高,SQL 會這樣理解:

「給我所有電子產品(任何價格)或是 500 元以下的電腦」

結果你會看到 2000 元的 MacBook 也跑出來,明明你不想要。

解法:用括號明確表達意圖

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

現在 SQL 知道了:先篩選這兩個類別,然後對所有結果套用價格條件。

我的原則:只要混用 ANDOR,我一定加括號。每一次。就算我很確定優先順序也一樣。這能避免 bug,也讓半年後的自己看懂當初在想什麼。


錯誤 4:到處使用 SELECT *

我懂,當你在探索一張新資料表時,打 SELECT * 又快又方便:

SELECT * FROM customers;

但這裡有個重點,我希望有人早點告訴我:不要讓這個習慣進到正式程式碼裡。

為什麼?三個理由:

  1. **效能殺手:**你撈了一堆用不到的欄位,浪費記憶體和網路頻寬
  2. **未來會爆炸:**下個月有人新增一個欄位,你的程式突然收到意料外的資料
  3. **意圖不明:**半年後你(或同事)看到這段程式,根本不知道到底哪些欄位重要

明確指定欄位:

SELECT customer_id, first_name, email
FROM customers;

這樣更快、更安全,而且一看就知道需要什麼資料。

SELECT * 只用在:快速探索資料、測試查詢。絕對不要用在應用程式裡。未來的你會感謝現在的你。


錯誤 5:用 LIMIT 卻不加 ORDER BY

你想看幾筆範例資料:

SELECT * FROM orders
LIMIT 10;

執行,得到 10 筆。看起來沒問題。

再執行一次。得到......不一樣的 10 筆?

沒有 ORDER BY 的話,資料庫會用最方便的順序回傳資料——也就是隨機的。小資料表可能看起來固定,但在真正的生產環境資料表(幾千幾萬筆),每次執行都可能得到不同結果。

這讓 debug 變得不可能,也會讓你的應用程式行為不一致。

永遠搭配 ORDER BY 使用:

SELECT * FROM orders
ORDER BY order_date DESC
LIMIT 10;

現在你穩定地拿到最新的 10 筆訂單。可預測、可 debug、可靠。

如果你不在乎順序,那你可能根本不需要 LIMIT——你只是在探索資料而已。但如果你在應用程式裡用 LIMIT,你一定在乎拿到哪些資料,所以一定要指定 ORDER BY


錯誤 6:在計算中忽略 NULL

這個錯誤很狡猾,因為它有時候能用......直到它不能用。

你計算折扣後的價格:

SELECT 
product_name,
price,
discount,
price - discount AS sale_price
FROM products;

有折扣的商品都很好。但一旦遇到 discount 是 NULL 的商品,整個計算結果就變成 NULL。

因為:100 - NULL = NULL

不是 100。是 NULL。

任何涉及 NULL 的算術運算都會產生 NULL。NULL 會「感染」整個計算。

解法:用 COALESCE() 提供預設值

SELECT 
product_name,
price,
discount,
price - COALESCE(discount, 0) AS sale_price
FROM products;

COALESCE(discount, 0) 的意思是:「如果 discount 有值就用它,如果是 NULL 就用 0 代替。」

這個技巧超實用:

  • total_sales / COALESCE(order_count, 1) — 避免除以零
  • COALESCE(middle_name, '') — 把 NULL 轉成空字串
  • COALESCE(bonus, 0) — 把沒有獎金視為零

錯誤 7:在 WHERE 中使用欄位別名

這個一開始會讓所有人困惑,因為看起來應該要能用:

SELECT 
product_name,
price * 1.1 AS price_with_tax
FROM products
WHERE price_with_tax > 100;

錯誤:「欄位 'price_with_tax' 不存在。」

可是......它明明就在那裡啊!你剛剛才定義的!

問題在於:SQL 處理子句的順序是固定的。WHERESELECT 之前執行,所以資料庫處理 WHERE 時,你的別名還不存在。

你必須重複計算:

SELECT 
product_name,
price * 1.1 AS price_with_tax
FROM products
WHERE price * 1.1 > 100;

有點煩,但這就是 SQL 的運作方式。

好消息:在 ORDER BY 中可以用別名,因為它在 SELECT 之後執行:

SELECT 
salary * 12 AS annual_salary
FROM employees
ORDER BY annual_salary DESC; -- 這個可以!

練習題

在關掉這篇文章前,試著修正這段查詢——它包含了今天提到的 3 個錯誤:

SELECT * FROM employees
WHERE department = Sales
OR salary > 50000
AND manager_id = NULL
LIMIT 5;

找到問題了嗎?(答案在下面)

.

.

.

答案:

  1. 缺少引號:應該是 'Sales'
  2. 缺少括號:應該是 (department = 'Sales' OR salary > 50000)
  3. NULL 檢查錯誤:應該是 IS NULL
  4. 加分題:LIMIT 前應該加 ORDER BY

你答對幾個?


寫在最後

SQL 是一個強大的工具,但就像所有工具一樣,需要時間和實踐才能精通。這些錯誤不是你的錯——它們是每個學習者必經的路。

重點是:認識它們、理解為什麼會犯這些錯,然後建立更好的習慣。

如果這篇文章幫你省下了 debug 的時間,或是讓你「啊哈!原來是這樣」,歡迎分享給其他正在學 SQL 的朋友。大家一起進步。

有任何 SQL 相關的問題或心得,也歡迎在底下留言討論。我們一起學習!


關於作者:

我是 Leon(亮之),一個熱愛分享技術知識的工程師。這個系列文章記錄了我學習 SQL 的歷程,希望能幫助更多人少走彎路。如果喜歡這篇文章,歡迎追蹤我的方格子,我會持續分享更多實用的程式技巧!

留言
avatar-img
留言分享你的想法!
avatar-img
Leon Wong 282
3會員
17內容數
Hi,我是 Leon Wong(亮之)——電腦科學與開發愛好者,也是 Notion 重度使用者。如果你想更高效地學習與創作,這裡會是你的實用資源。
Leon Wong 282的其他內容
2025/10/16
上週,我花了 20 分鐘在 Word 裡排版一份文件。標題調得漂漂亮亮,項目符號排列整齊,字體大小都恰到好處。按下傳送鍵,信心滿滿地等待同事回覆。 結果呢? 「欸,你傳的檔案格式跑掉了耶。」同事傳來訊息,還附上一張慘不忍睹的截圖——我的精心排版完全崩潰,看起來就像綁匪的恐嚇信。 我知道你一定也
2025/10/16
上週,我花了 20 分鐘在 Word 裡排版一份文件。標題調得漂漂亮亮,項目符號排列整齊,字體大小都恰到好處。按下傳送鍵,信心滿滿地等待同事回覆。 結果呢? 「欸,你傳的檔案格式跑掉了耶。」同事傳來訊息,還附上一張慘不忍睹的截圖——我的精心排版完全崩潰,看起來就像綁匪的恐嚇信。 我知道你一定也
2025/10/15
你剛發現 Markdown 這個東西,每個人都說它「很簡單」,但你盯著那些星號、井字號和括號,完全不知道從何下手。 同事隨口提到他所有文件都用 Markdown 寫。你喜歡的技術部落格用它。GitHub 上到處都是 README 檔案。但當你試著自己學習時,那些文件讓人頭昏腦脹,教學又假設你已經懂
2025/10/15
你剛發現 Markdown 這個東西,每個人都說它「很簡單」,但你盯著那些星號、井字號和括號,完全不知道從何下手。 同事隨口提到他所有文件都用 Markdown 寫。你喜歡的技術部落格用它。GitHub 上到處都是 README 檔案。但當你試著自己學習時,那些文件讓人頭昏腦脹,教學又假設你已經懂
2025/10/14
技術寫作時圖片總是出現問題?本文分享作者三年測試十幾個圖床的經驗,包含Imgur、Cloudflare R2等,並介紹uPic、PicGo等上傳工具,教你建立一套自動化、跨平臺、穩定的Markdown圖片管理系統。
Thumbnail
2025/10/14
技術寫作時圖片總是出現問題?本文分享作者三年測試十幾個圖床的經驗,包含Imgur、Cloudflare R2等,並介紹uPic、PicGo等上傳工具,教你建立一套自動化、跨平臺、穩定的Markdown圖片管理系統。
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
※ 把record加到table有兩種方式: VALUES • SELECT ※ 語法 INSERT INTO VALUES 語法: Record 代表一組值的集合,每個值對應到表格中的一個欄位(column)。 INSERT INTO 語法用來指定要插入資料的表格。 需要提供一個
Thumbnail
※ 把record加到table有兩種方式: VALUES • SELECT ※ 語法 INSERT INTO VALUES 語法: Record 代表一組值的集合,每個值對應到表格中的一個欄位(column)。 INSERT INTO 語法用來指定要插入資料的表格。 需要提供一個
Thumbnail
※ 什麼是WHERE? 使用 WHERE來設定條件,可以幫助我們縮小查詢結果的範圍,取得想要的結果。 ※ 語法: ※ 解析順序: From:先看是哪一張table→table裡面符合Where指定條件的record→再看Select指定的是那些欄位→再根據那個欄位進行排序。 ※ 使⽤⽅
Thumbnail
※ 什麼是WHERE? 使用 WHERE來設定條件,可以幫助我們縮小查詢結果的範圍,取得想要的結果。 ※ 語法: ※ 解析順序: From:先看是哪一張table→table裡面符合Where指定條件的record→再看Select指定的是那些欄位→再根據那個欄位進行排序。 ※ 使⽤⽅
Thumbnail
※ 為什麼選擇SQLite? 安裝簡單:SQLite是一個零配置的資料庫,不需要複雜的設定和安裝過程。。 使用SQL語法。 設計選擇多元性(MySQL / SQLite):適合於小零件資料應用、嵌入式系統、物聯網設備。 ※ SQLite四大優點: 執行檔檔案很小:資料庫系統需要的磁碟空
Thumbnail
※ 為什麼選擇SQLite? 安裝簡單:SQLite是一個零配置的資料庫,不需要複雜的設定和安裝過程。。 使用SQL語法。 設計選擇多元性(MySQL / SQLite):適合於小零件資料應用、嵌入式系統、物聯網設備。 ※ SQLite四大優點: 執行檔檔案很小:資料庫系統需要的磁碟空
Thumbnail
SEO 寫作有一些常見的錯誤,包括標題不守承諾、花式離題、行文順序顛倒等。換個角度思考,以讀者為主,可以大幅提升 SEO 寫作的效果。
Thumbnail
SEO 寫作有一些常見的錯誤,包括標題不守承諾、花式離題、行文順序顛倒等。換個角度思考,以讀者為主,可以大幅提升 SEO 寫作的效果。
Thumbnail
這篇文章主要是介紹了SQL查詢效能調校的方法,針對索引最佳化做了整理和分享,並提供了一些注意事項和建議。
Thumbnail
這篇文章主要是介紹了SQL查詢效能調校的方法,針對索引最佳化做了整理和分享,並提供了一些注意事項和建議。
Thumbnail
介紹工作後幾個常見的小問題,包括寫 Log 的好習慣、本地印出錯誤或過程、PHPCS 工具、變數儲存於設定檔、避免魔術數字、程式碼靜態分析與動態分析。
Thumbnail
介紹工作後幾個常見的小問題,包括寫 Log 的好習慣、本地印出錯誤或過程、PHPCS 工具、變數儲存於設定檔、避免魔術數字、程式碼靜態分析與動態分析。
Thumbnail
軟體系統的發展歷程大多相似,首重解決基本需求、提供操作介面,進而提升安全性、擴充功能、優化操作。
Thumbnail
軟體系統的發展歷程大多相似,首重解決基本需求、提供操作介面,進而提升安全性、擴充功能、優化操作。
追蹤感興趣的內容從 Google News 追蹤更多 vocus 的最新精選內容追蹤 Google News