處理 NULL 會在各種場景遇到:從報表裡缺資料的處理,到過濾和排序。如果要在表格裡選「沒資料」跟一個奇怪的數字像 9999,大部分人都會選 NULL —— 對啦,雖然不是最方便,但至少很誠實。我們來看幾個常見的情境。
範例:排序沒有價格的商品
假設我們在經營一個網路商店,有一個商品表:
| product_id | name | price |
|---|---|---|
| 1 | 手機 | 45000 |
| 2 | 筆電 | NULL |
| 3 | 相機 | 25000 |
| 4 | 智慧手錶 | NULL |
我們想要依照價格排序商品,沒有價格(NULL)的要排在最後面。
SELECT product_id, name, price
FROM products
ORDER BY price ASC NULLS LAST;
結果:
| product_id | name | price |
|---|---|---|
| 3 | 相機 | 25000 |
| 1 | 手機 | 45000 |
| 2 | 筆電 | NULL |
| 4 | 智慧手錶 | NULL |
注意 NULLS LAST 這個關鍵字。預設 PostgreSQL 在 ASC 會把 NULL 放最前面,但加這個參數就會移到最後。
範例:過濾沒有生日的學生
我們有一個學生表,只想選出沒有填生日的學生。
| student_id | name | birth_date |
|---|---|---|
| 1 | Otto Art | 2000-01-15 |
| 2 | Anna Song | NULL |
| 3 | Alex Lin | 1999-05-10 |
| 4 | Maria Chi | NULL |
查詢:
SELECT student_id, name
FROM students
WHERE birth_date IS NULL;
結果:
| student_id | name |
|---|---|
| 2 | Anna Song |
| 4 | Maria Chi |
我們成功抓出生日未知的學生資料。
處理 NULL 的函數用法範例
範例:計算總金額時考慮 NULL
訂單表裡有訂單金額,但有時候資料沒填好,這時我們要把金額當成 0。
資料範例:
| order_id | customer_name | order_amount |
|---|---|---|
| 1 | Alex | 1200 |
| 2 | Maria | 2500 |
| 3 | Max | NULL |
| 4 | Xena | 3100 |
查詢:
SELECT SUM(COALESCE(order_amount, 0)) AS total_amount
FROM orders;
結果:
| total_amount |
|---|
| 6800 |
我們用 COALESCE(order_amount, 0) 把 NULL 先換成 0 再加總,這樣就不會算錯或出錯。
範例:用文字取代 NULL
| customer_name | order_amount |
|---|---|
| Alex | 1200 |
| Maria | 2500 |
| Max | NULL |
| Xena | 3100 |
報表裡要把所有空值顯示成「未填寫」而不是 NULL。
SELECT
customer_name,
COALESCE(order_amount::TEXT, '未填寫') AS order_status
FROM orders;
結果:
| customer_name | order_status |
|---|---|
| Alex | 1200 |
| Maria | 2500 |
| Max | 未填寫 |
| Xena | 3100 |
COALESCE() 可以讓你在 NULL 時顯示你想要的文字。
進階 NULL 處理情境
| customer_name | order_amount |
|---|---|
| Alex | 1200 |
| Maria | 2500 |
| Max | NULL |
| Xena | 3100 |
我們的任務——把沒有金額的訂單排在最前面,然後剩下的從大到小排序。
SELECT customer_name, order_amount
FROM orders
ORDER BY order_amount DESC NULLS FIRST;
結果:
| customer_name | order_amount |
|---|---|
| Max | NULL |
| Xena | 3100 |
| Maria | 2500 |
| Alex | 1200 |
這裡我們用 NULLS FIRST,讓 NULL 的值排在最前面。
範例:過濾資料並取代 NULL 值
| student_id | name | birth_date |
|---|---|---|
| 1 | Otto Art | 2000-01-15 |
| 2 | Anna Song | NULL |
| 3 | Alex Lin | 1999-05-10 |
| 4 | Maria Chi | NULL |
有些報表要只顯示有填資料的行,或是把 NULL 換成「未知」。
SELECT
student_id,
name,
COALESCE(birth_date::TEXT, '未知') AS birth_date_info
FROM students;
結果:
| student_id | name | birth_date_info |
|---|---|---|
| 1 | Otto Art | 2000-01-15 |
| 2 | Anna Song | 未知 |
| 3 | Alex Lin | 1999-05-10 |
| 4 | Maria Chi | 未知 |
這在做報表時很有用,能清楚標示資料缺失。
實用建議
處理 NULL 要特別小心。這裡有幾個小撇步:
- 用
IS NULL跟COALESCE()來檢查和取代缺值。 - 記得聚合函數會忽略
NULL,除了COUNT(*)。 - 排序時記得
NULLS FIRST跟NULLS LAST這兩個關鍵字。 - 報表裡一定要說明你怎麼處理
NULL,這樣同事才不會誤會。
這些技巧不只讓你寫出正確的查詢,還能在面試時讓人覺得你很懂實戰。畢竟會處理真實資料比只會理論更吃香啦!
GO TO FULL VERSION