ISNULL() / IFNULL() / NVL() 函數 (SQL NULL Handling Functions)

這些函數用來檢查值是否為 NULL,如果是 NULL 就替換成指定的預設值。不同資料庫有不同的函數名稱。

各資料庫語法

資料庫函數語法
SQL ServerISNULL()ISNULL(expression, replacement)
MySQLIFNULL()IFNULL(expression, replacement)
OracleNVL()NVL(expression, replacement)
PostgreSQLCOALESCE()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:

idnamephonediscount
1張一02-1234567810
2王二NULLNULL
3李三03-87654321NULL

實際應用範例

計算時將 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 標準且功能更強大。