我們來聊聊另一個用來處理神祕 NULL 的函數 — NULLIF()。這傢伙在你需要把某些值換成 NULL 來正確處理資料時超好用。繫好安全帶,這會是個有趣的旅程!
NULLIF() 函數在 PostgreSQL 裡超實用,可以讓你比較兩個值,如果一樣就回傳 NULL,不一樣就回傳第一個值。它就像在說:「如果這兩個值一樣,就直接忘了它們吧!」
這是它的簡單語法:
NULLIF(value1, value2)
如果 value1 跟 value2 一樣,結果就是 NULL。如果不一樣,結果就是 value1。
範例:
SELECT NULLIF(10, 10); -- 結果: NULL
SELECT NULLIF(10, 20); -- 結果: 10
SELECT NULLIF('hello', 'hello'); -- 結果: NULL
SELECT NULLIF('hello', 'world'); -- 結果: 'hello'
很簡單吧?現在我們來看看怎麼在實際情境中用這個函數。
範例 1:避免除以零
除以零是每個工程師的惡夢。在 SQL 裡如果你試著除以零會直接噴錯。這時 NULLIF() 就能派上用場啦。
想像一下:我們有個 sales 表,有兩個欄位:revenue(收入)和 expenses(支出)。我們想算支出的獲利率(revenue / expenses),但有時支出是零。如果直接查詢沒檢查,會直接出現除以零的錯誤。
sales 表:
| revenue | expenses |
|---|---|
| 1000 | 200 |
| 1500 | 0 |
| 2000 | 250 |
錯誤的查詢:
SELECT revenue / expenses AS profitability
FROM sales;
-- 錯誤: 除以零!
用 NULLIF() 解決:
SELECT revenue / NULLIF(expenses, 0) AS profitability
FROM sales;
結果:
| profitability |
|---|
| 5.00 |
| NULL |
| 8.00 |
現在如果 expenses 是 0,NULLIF(expenses, 0) 會回傳 NULL,而除以 NULL 不會噴錯,只會回傳 NULL。
範例 2:把一樣的值換成 NULL
想像你有個學生資料表,有 first_name 跟 preferred_name 兩個欄位。有時候學生喜歡用本名,有時候會選別的。如果兩個名字一樣,其實就不用顯示 preferred_name 了。
students 表:
| first_name | preferred_name |
|---|---|
| John | Johnny |
| Anna | Anna |
| Alex | Lex |
用 NULLIF() 查詢:
SELECT first_name,
NULLIF(preferred_name, first_name) AS display_name
FROM students;
結果:
| first_name | display_name |
|---|---|
| John | Johnny |
| Anna | NULL |
| Alex | Lex |
當 preferred_name 跟 first_name 一樣時,結果就會是 NULL。
範例 3:資料過濾
有時候你只想選出兩個欄位值不一樣的資料。例如有個訂單表,裡面有 original_price 跟 discounted_price。我們想找出有打折的訂單。
orders 表:
| order_id | original_price | discounted_price |
|---|---|---|
| 1 | 100 | 100 |
| 2 | 200 | 180 |
| 3 | 150 | 150 |
用 NULLIF() 查詢:
SELECT order_id, original_price, discounted_price
FROM orders
WHERE NULLIF(original_price, discounted_price) IS NOT NULL;
結果:
| order_id | original_price | discounted_price |
|---|---|---|
| 2 | 200 | 180 |
只有有打折的訂單會出現在結果裡。
NULLIF() 的實用案例
案例 1:選擇可選值
有時候你要從多個欄位選一個值,但要排除掉某些特定值。例如有個員工表,裡面有 base_salary 跟 bonus。如果 bonus 是 0,我們想把它設成 999。
employees 表:
| employee_id | base_salary | bonus |
|---|---|---|
| 1 | 50000 | 10000 |
| 2 | 40000 | 0 |
| 3 | 60000 | 5000 |
用 NULLIF() 查詢:
SELECT employee_id,
base_salary + COALESCE(NULLIF(bonus, 0), 999) AS total_salary
FROM employees;
結果:
| employee_id | total_salary |
|---|---|
| 1 | 60000 |
| 2 | 40999 |
| 3 | 65000 |
如果 bonus 是 0,就會變成 999。
案例 2:計算行數
我們可以用 NULLIF() 來簡化複雜的過濾條件。像是有個用戶表,我們想一次查出總用戶數和已註冊用戶數(不含 guest 狀態)。
SELECT
COUNT(*) AS total_users,
COUNT(NULLIF(status, 'guest')) AS registered_users
FROM users;
就這樣,只用一個 NULLIF() 函數,我們就能搞定超多事:從避免錯誤到讓程式碼更好懂。現在你知道它怎麼用了,離 PostgreSQL 資料處理高手又更近一步啦!
GO TO FULL VERSION