Pregunta 1¿Cuál de las siguientes describe correctamente ORDER BY CASE WHEN city = 'Tokyo' THEN 1 WHEN city = 'Osaka' THEN 2 ELSE 9 END?
Funciones ⑥ — CASE en la práctica — ORDER BY / UPDATE / NULL
El sexto artículo sobre funciones SQL. Asignar un orden arbitrario con ORDER BY CASE, actualizaciones masivas condicionales con UPDATE ~ SET columna = CASE, y el manejo de CASE con NULL — usando datos staff y customer cargados desde CSV.
Datos usados en este artículo — staff y customer
El CASE aprendido hasta ahora es una expresión de propósito general que puedes colocar no solo en la lista de columnas del SELECT sino también dentro de `ORDER BY` y en una cláusula SET de `UPDATE`. Este artículo recorre esas dos aplicaciones y la trampa de manejar NULL con CASE en orden.
El sujeto es la tabla staff (10 empleados) en la primera mitad y la tabla customer (8 clientes / contiene NULL) en la segunda. La primera mitad ordena city en un orden arbitrario; la segunda mitad usa un CASE que muestra el email NULL como "Not registered", y finalmente ejecuta un UPDATE CASE que reescribe los valores de country en categorías de región.
Usar CASE en ORDER BY — asignar un orden arbitrario
El lado derecho de ORDER BY puede contener no solo un nombre de columna sino también una expresión CASE. Con esto puedes asignar un orden arbitrario que el orden alfabético de cadenas o el tamaño numérico no pueden producir. Úsalo para prioridades de negocio como "Tokyo → Osaka → Kyoto → otros", órdenes de estado como "Open → In progress → Done", o un orden por ranking.
Escríbelo como ORDER BY CASE WHEN cond THEN número ... ELSE número END — CASE devuelve un número para ordenar y ordenas por ese número. ASC / DESC se pueden añadir igual que a una columna. Las filas con el mismo número se ordenan por la siguiente columna de ORDER BY (separada por comas), así que combinar clave de orden + clave secundaria también determina el orden dentro de una categoría.
-- 1) Ordena city en el orden 'Osaka → Kyoto → Tokyo → otros'
SELECT name, city, salary FROM staff
ORDER BY
CASE city
WHEN 'Osaka' THEN 1
WHEN 'Kyoto' THEN 2
WHEN 'Tokyo' THEN 3
ELSE 9
END,
salary DESC; -- dentro de la misma city, primero el salario más alto
-- 2) ORDER BY CASE + DESC también puede invertir el orden
-- si CASE asigna 1, 2, 3, entonces DESC los ordena 3, 2, 1
La trampa de CASE + NULL — usa `IS NULL`, no `= NULL`
Igual que en WHERE, `= NULL` / `<> NULL` tampoco se pueden usar dentro de CASE. Una comparación con NULL siempre resulta en NULL (desconocido), y cuando una cláusula CASE WHEN devuelve NULL esa rama no se toma, así que el resultado difiere de lo que pretendías.
Para probar si hay NULL, usa `columna IS NULL` / `columna IS NOT NULL`. Esta es la misma regla que la comprobación de NULL en WHERE aprendida antes, y es común a todo lugar donde se pueda escribir una condición — CASE / IIF / WHERE / ON. La forma simple (CASE columna WHEN ... THEN) no puede probar si hay NULL, así que cuando necesites manejar NULL usa siempre la forma con búsqueda (CASE WHEN columna IS NULL THEN ...).
-- Incorrecto: WHEN NULL no puede seleccionar filas NULL ('Unknown' nunca se muestra)
SELECT name, age,
CASE age
WHEN NULL THEN 'Unknown'
ELSE age
END AS age_display
FROM customer;
-- Correcto: forma con búsqueda + IS NULL
SELECT name, age,
CASE
WHEN age IS NULL THEN 'Unknown'
ELSE age
END AS age_display
FROM customer;
-- Nota: COALESCE(age, 'Unknown') da el mismo resultado
-- para un simple reemplazo de NULL de 2 valores, COALESCE es más corto
Usar CASE en UPDATE — reescribir valores según una condición
Hasta ahora CASE ha generado una columna nueva en el lado de lectura, pero escribir CASE en una cláusula SET de UPDATE te permite reescribir los valores reales de la columna en la tabla según una condición.
Escríbelo como UPDATE tabla SET columna = CASE WHEN cond THEN valor1 WHEN cond THEN valor2 ... ELSE columna END. Escribir ELSE columna para decir "las filas que no coinciden con ningún WHEN conservan su valor original" es la forma segura; olvídalo y ELSE se trata como NULL, sobrescribiendo con NULL las filas que no son objetivo.
Como UPDATE es una operación destructiva que cambia la tabla real, este artículo lo trata en el ejercicio final. Antes de ejecutarlo, la práctica estándar en producción es probar la misma condición con SELECT name, columna, CASE ..., verificar visualmente el resultado y reescribirlo como UPDATE solo si tiene buen aspecto.
-- Primero verifica con SELECT (con la intención de poner a 0 el age NULL)
SELECT name, age,
CASE
WHEN age IS NULL THEN 0
ELSE age
END AS new_age
FROM customer;
-- Si tiene buen aspecto, reescríbelo como UPDATE
UPDATE customer SET age = CASE
WHEN age IS NULL THEN 0
ELSE age
END;
Verificación de conocimientos
Responde cada pregunta una a una.
Pregunta 2¿Cuál de las siguientes es la forma correcta de manejar NULL con CASE?
Pregunta 3En UPDATE customer SET country = CASE WHEN country IN ('Japan') THEN 'Asia' WHEN country IS NULL THEN 'Unknown' ELSE country END;, ¿cuál es la mejor razón para escribir `ELSE country`?