就像寫其他程式一樣,寫 SELECT 的時候出錯是很正常的。就算是超有經驗的工程師,SQL 查詢有時還是會有 bug。今天我們來拆解一下用 SELECT 時常見的錯誤、為什麼會發生,還有怎麼避免。
SQL 這語言對語法規則超級嚴格。少一個逗號、多一個逗號、少了個關鍵字或是單字順序錯了,資料庫馬上就會「舉紅旗」給你看。
漏掉關鍵字
最常見的錯誤就是很單純地忘記某個必須的關鍵字。舉個例子,來看這個指令:
SELECT name age FROM students;
是不是覺得哪裡怪怪的?這裡少了 , 關鍵字,應該放在 name 跟 age 之間。修正一下:
SELECT name, age FROM students;
這種錯誤很常見,因為你可能還在學怎麼寫查詢,或是只是太趕了。SQL 不喜歡你趕時間啦!
欄位或資料表名稱拼錯
SQL 指令對欄位名和資料表名很敏感。來看這個查詢:
SELECT naem, agge FROM studnts;
資料庫看到這個會覺得你在亂寫:naem 跟 agge 這兩個欄位還有 studnts 這個表根本不存在。修正一下:
SELECT name, age FROM students;
小建議:如果你不確定欄位名,可以在 psql 裡用 \d table_name,或是用 pgAdmin 的介面查一下表結構。
忘記加引號
如果欄位名或表名有空格或特殊符號,要用雙引號包起來。像這樣:
SELECT "first name", age FROM students;
如果忘記加引號,SQL 會看不懂你在幹嘛,直接報錯。
邏輯錯誤:查詢能跑但結果怪怪的
有時候查詢能順利執行,但結果就是「怪怪的」。這就是邏輯錯誤。這種錯誤比較陰險,因為資料庫不會告訴你哪裡怪。
- 比較運算子用錯。假設你想查所有年齡大於 18 歲的學生:
SELECT * FROM students WHERE age > 18;
再來換個運算子:
SELECT * FROM students WHERE age = 18;
這個查詢只會回傳 剛好 18 歲的學生。如果你本來想查所有超過 18 歲的,這就是邏輯錯誤啦。
小提醒:這種細節要很小心。如果不確定,先用小一點的資料(像 LIMIT)試試看。
條件組合錯誤
來看個例子:
SELECT * FROM students WHERE age > 18 OR grade = 'A' AND city = 'New York';
這個查詢可能會意外查到不住在紐約的學生。為什麼?因為 SQL 會先處理 AND,再處理 OR。我們用括號重寫一下:
SELECT * FROM students WHERE (age > 18 OR grade = 'A') AND city = 'New York';
這樣才對啦。
沒加過濾條件
有時候像 SELECT * FROM students; 這種查詢會回傳一大堆資料,但你其實只想找特定城市的學生。怎麼辦?加個 WHERE 過濾一下:
SELECT * FROM students WHERE city = 'New York';
效能問題
查詢資料量一大,優化就超重要。來看看常見會拖慢效能的錯誤。
像 SELECT * 這種查詢在開發時很方便,但實際上會拖慢效能。如果你只要特定欄位,記得寫出來。
-- 不建議這樣寫:
SELECT * FROM students;
-- 推薦這樣寫:
SELECT name, age FROM students;
為什麼這很重要?SELECT * 會抓出所有欄位,就算你根本沒用到。這會讓資料量變很大。
實用小技巧:怎麼避免出錯
只要照幾個小建議,SQL 查詢就能寫得更穩:
- 執行前先檢查語法:用 IDE 或
pgAdmin的提示功能,錯誤會先提醒你。 - 先從小資料開始查。加個
LIMIT 5或LIMIT 10先測試。 - 多寫註解,方便自己看懂查詢在幹嘛:
-- 查所有年齡大於 18 歲的學生 SELECT name, age FROM students WHERE age > 18; - 用不同資料測試,確認邏輯沒問題。
- 不要亂用
SELECT *,尤其是大表。
面試常見陷阱
SQL 面試很愛考你找查詢裡的錯誤。像這樣:
SELECT name FROM employees WHERE salary > 50000 ORDER BY department;
想一下:這查詢邏輯對嗎?如果用了 ORDER BY,通常應該是要照薪水排序:
SELECT name FROM employees WHERE salary > 50000 ORDER BY salary DESC;
寫 SELECT 是 SQL 的基本功,一開始出錯很正常。慢慢練,你會發現寫查詢就像打訊息一樣簡單。畢竟,真正的工程師不只會跟貓玩,也會玩資料庫啦。😉
GO TO FULL VERSION