ISNULL() / IFNULL() / NVL() 函數 (SQL NULL Handling Functions)
這些函數用來檢查值是否為 NULL,如果是 NULL 就替換成指定的預設值。不同資料庫有不同的函數名稱。
各資料庫語法
| 資料庫 | 函數 | 語法 |
|---|---|---|
| SQL Server | ISNULL() | ISNULL(expression, replacement) |
| MySQL | IFNULL() | IFNULL(expression, replacement) |
| Oracle | NVL() | NVL(expression, replacement) |
| PostgreSQL | COALESCE() | COALESCE(expression, replacement) |
COALESCE() 是 SQL 標準函數,所有資料庫都支援,且可以接受多個參數。
SQL Server - ISNULL()
SELECT ISNULL(NULL, 'N/A');
-- 結果: N/A
SELECT ISNULL('Hello', 'N/A');
-- 結果: Hello
-- 實際應用:顯示客戶電話,若無則顯示「無電話」
SELECT name, ISNULL(phone, '無電話') AS phone
FROM customers;
MySQL - IFNULL()
SELECT IFNULL(NULL, 'N/A');
-- 結果: N/A
SELECT IFNULL('Hello', 'N/A');
-- 結果: Hello
-- 實際應用
SELECT name, IFNULL(phone, '無電話') AS phone
FROM customers;
MySQL 還有另一個函數 ISNULL(),但它只是用來判斷是否為 NULL,回傳 1 或 0:
SELECT ISNULL(NULL); -- 結果: 1
SELECT ISNULL('Hello'); -- 結果: 0
Oracle - NVL()
SELECT NVL(NULL, 'N/A') FROM dual;
-- 結果: N/A
SELECT NVL('Hello', 'N/A') FROM dual;
-- 結果: Hello
-- 實際應用
SELECT name, NVL(phone, '無電話') AS phone
FROM customers;
Oracle 還有 NVL2() 函數,可以分別指定 NULL 和非 NULL 時的回傳值:
-- NVL2(expression, value_if_not_null, value_if_null)
SELECT NVL2(phone, '有電話', '無電話') FROM customers;
範例資料表
假設有一個客戶資料表 customers:
| id | name | phone | discount |
|---|---|---|---|
| 1 | 張一 | 02-12345678 | 10 |
| 2 | 王二 | NULL | NULL |
| 3 | 李三 | 03-87654321 | NULL |
實際應用範例
計算時將 NULL 當作 0
-- SQL Server
SELECT name, price * (1 - ISNULL(discount, 0) / 100) AS final_price
FROM products;
-- MySQL
SELECT name, price * (1 - IFNULL(discount, 0) / 100) AS final_price
FROM products;
顯示友善的資訊
-- SQL Server
SELECT
name,
ISNULL(phone, '未提供') AS phone,
ISNULL(CAST(discount AS VARCHAR) + '%', '無折扣') AS discount
FROM customers;
與 COALESCE 的比較
ISNULL/IFNULL/NVL 只能接受兩個參數,而 COALESCE 可以接受多個參數,回傳第一個非 NULL 的值:
-- COALESCE 可以有多個備選值
SELECT COALESCE(phone1, phone2, phone3, '無電話') AS phone
FROM customers;
-- 使用 ISNULL 需要巢狀
SELECT ISNULL(phone1, ISNULL(phone2, ISNULL(phone3, '無電話'))) AS phone
FROM customers;
建議優先使用 COALESCE,因為它是 SQL 標準且功能更強大。