COALESCE y NULLIF
BásicoCOALESCE(a, b, …) devuelve el primer argumento que no sea NULL: sirve para poner un valor por defecto. NULLIF(a, b) hace lo contrario: devuelve NULL cuando a es igual a b. Su uso más común es x / NULLIF(y, 0), que devuelve NULL en lugar de fallar cuando el divisor es 0.
Sintaxis
COALESCE(columna, 'valor por defecto')
dividendo / NULLIF(divisor, 0)Ejemplo
SELECT
o.id,
o.status,
o.subtotal,
o.discount,
round(100 * o.discount / NULLIF(o.subtotal, 0), 1) AS pct_descuento,
COALESCE(o.courier_id::text, 'sin asignar') AS repartidor
FROM orders AS o
WHERE o.promotion_id = 4
AND o.id BETWEEN 60 AND 90
ORDER BY o.id;Resultado
| id | status | subtotal | discount | pct_descuento | repartidor |
|---|---|---|---|---|---|
| 60 | delivered | 63639.00 | 4050.00 | 6.4 | 112 |
| 61 | cancelled | 30888.00 | 4050.00 | 13.1 | sin asignar |
| 73 | cancelled | 0.00 | 0.00 | NULL | sin asignar |
| 76 | delivered | 165.95 | 11.10 | 6.7 | 427 |
| 86 | cancelled | 94081.50 | 4050.00 | 4.3 | sin asignar |
Cómo leerlo
El pedido 73 tiene subtotal 0. Sin NULLIF, la división falla con «division by zero» y la consulta completa no devuelve nada. Con NULLIF, esa fila muestra NULL y las demás se calculan normalmente. Los pedidos cancelados no tienen repartidor, y COALESCE pone «sin asignar». Como courier_id es un número, se convierte a texto con ::text para que los dos argumentos de COALESCE sean del mismo tipo.
Error común
Así no
SELECT COALESCE(o.courier_id, 'sin asignar') AS repartidor
FROM orders AS o;Mezclar tipos en COALESCE. Todos los argumentos deben poder convertirse a un mismo tipo: aquí PostgreSQL intenta leer 'sin asignar' como número entero y da error. Convierte primero (o.courier_id::text) o usa un valor por defecto del mismo tipo que la columna.
En otros motores: MySQL, BigQuery, SQL Server, Oracle, Snowflake
MySQLBigQuery
IFNULL(a, b)es la versión de dos argumentos.COALESCEtambién existe y acepta más argumentos.IFNULL(courier_id, 0)SQL Server
ISNULL(a, b)toma dos argumentos y devuelve el tipo del primero, así que un texto por defecto más largo que la columna puede quedar recortado.COALESCEno tiene ese problema.ISNULL(courier_id, 0)OracleSnowflake
NVL(a, b)es la versión de dos argumentos.COALESCEyNULLIFfuncionan igual que en PostgreSQL en todos los motores de esta lista.NVL(courier_id, 0)
Estos fragmentos no se ejecutan en el curso: se muestran como referencia de cada motor.