IF
La función IF es la forma más directa de evaluar una condición en MySQL. Recibe tres argumentos: una condición, el valor a devolver si la condición es verdadera y el valor a devolver si es falsa. Es el equivalente al operador ternario (condicion ? valor_si : valor_no) de los lenguajes de programación.
Cuando solo necesitas elegir entre dos opciones, IF es más conciso que CASE. Sin embargo, para más de dos alternativas, CASE resulta más legible y mantenible.
Sintaxis
IF(condicion, valor_si_verdadero, valor_si_falso)MySQL evalúa la condición. Si es verdadera (distinta de cero y distinta de NULL), devuelve el segundo argumento. Si es falsa o NULL, devuelve el tercero. Siempre devuelve exactamente uno de los dos valores, nunca ambos ni ninguno.
Comportamiento básico
Para marcar productos según su disponibilidad en stock:
SELECT
nombre,
stock,
IF(stock > 0, 'Disponible', 'Agotado') AS disponibilidad
FROM productos
LIMIT 7;| nombre | stock | disponibilidad |
|---|---|---|
| iPhone 15 Pro | 45 | Disponible |
| Samsung Galaxy S24 | 62 | Disponible |
| Google Pixel 8 | 38 | Disponible |
| Xiaomi 14 | 80 | Disponible |
| MacBook Air M3 | 25 | Disponible |
| Funda iPhone silicona | 200 | Disponible |
| Cargador USB-C 65W | 150 | Disponible |
La función evalúa stock > 0 para cada fila. Cuando el stock es mayor que cero, devuelve 'Disponible'; en caso contrario, devuelve 'Agotado'. Este patrón es habitual para convertir valores numéricos en etiquetas legibles para el usuario.
También funciona con cálculos numéricos. Para aplicar un descuento solo a productos que superan cierto precio:
SELECT
nombre,
precio,
IF(precio > 1000, precio * 0.90, precio) AS precio_final
FROM productos
WHERE categoria_id IN (6, 7)
ORDER BY precio DESC;| nombre | precio | precio_final |
|---|---|---|
| ASUS ROG Zephyrus | 1899.99 | 1709.99 |
| Lenovo ThinkPad X1 | 1549.00 | 1394.10 |
| MacBook Air M3 | 1399.00 | 1259.10 |
| iPhone 15 Pro | 1299.99 | 1169.99 |
| Samsung Galaxy S24 | 899.99 | 899.99 |
| Google Pixel 8 | 699.00 | 699.00 |
| Xiaomi 14 | 599.99 | 599.99 |
Los productos con precio superior a 1000 euros reciben un 10% de descuento. El resto mantiene su precio original. Es una forma sencilla de implementar reglas de negocio directamente en la consulta.
Caso práctico: IF con funciones de agregación
IF combinado con SUM o COUNT permite contar o sumar filas que cumplen una condición específica, de manera similar a como se usa CASE para tablas pivote, pero con una sintaxis más compacta:
SELECT
COUNT(*) AS total_pedidos,
SUM(IF(estado = 'entregado', 1, 0)) AS entregados,
SUM(IF(estado = 'cancelado', 1, 0)) AS cancelados,
SUM(IF(estado = 'pendiente', total, 0)) AS importe_pendiente
FROM pedidos;| total_pedidos | entregados | cancelados | importe_pendiente |
|---|---|---|---|
| 25 | 5 | 3 | 2153.91 |
Cada SUM(IF(...)) funciona como un filtro dentro de la agregación. Cuando la condición se cumple, se suma 1 (para contar) o el valor de total (para sumar importes). Cuando no se cumple, se suma 0, que no afecta al resultado. Este patrón es más breve que el equivalente con CASE, aunque ambos producen el mismo resultado.
Caso práctico: IF en ORDER BY
Puedes usar IF para alterar el orden de clasificación según una condición. Por ejemplo, para mostrar primero los productos con stock bajo:
SELECT
nombre,
stock,
precio
FROM productos
ORDER BY IF(stock < 20, 0, 1), stock ASC
LIMIT 8;| nombre | stock | precio |
|---|---|---|
| Sofá 3 plazas | 8 | 599.00 |
| ASUS ROG Zephyrus | 12 | 1899.99 |
| Escritorio ajust. | 15 | 449.00 |
| Lenovo ThinkPad X1 | 18 | 1549.00 |
| MacBook Air M3 | 25 | 1399.00 |
| Google Pixel 8 | 38 | 699.00 |
| iPhone 15 Pro | 45 | 1299.99 |
| Samsung Galaxy S24 | 62 | 899.99 |
La expresión IF(stock < 20, 0, 1) asigna el valor 0 a los productos con stock bajo y 1 al resto. Como ORDER BY ordena de menor a mayor por defecto, los productos con stock bajo (valor 0) aparecen primero. Dentro de cada grupo, se ordenan por stock ascendente.
Caso práctico: IF anidado
Puedes anidar funciones IF para manejar más de dos opciones:
SELECT
nombre,
precio,
IF(precio >= 1000, 'Alto',
IF(precio >= 300, 'Medio', 'Bajo')
) AS rango_precio
FROM productos
LIMIT 6;| nombre | precio | rango_precio |
|---|---|---|
| iPhone 15 Pro | 1299.99 | Alto |
| Samsung Galaxy S24 | 899.99 | Medio |
| Google Pixel 8 | 699.00 | Medio |
| Xiaomi 14 | 599.99 | Medio |
| Funda iPhone silicona | 49.99 | Bajo |
| Cargador USB-C 65W | 35.99 | Bajo |
Aunque funciona, la legibilidad se deteriora rápidamente con más de dos niveles de anidación. Con tres niveles ya resulta difícil de seguir. En estos casos, CASE es la opción preferida:
-- Equivalente con CASE, mucho más legible
SELECT
nombre,
precio,
CASE
WHEN precio >= 1000 THEN 'Alto'
WHEN precio >= 300 THEN 'Medio'
ELSE 'Bajo'
END AS rango_precio
FROM productos
LIMIT 6;La versión con CASE produce el mismo resultado pero es más fácil de leer, modificar y ampliar. Como regla general, usa IF cuando solo hay dos opciones y CASE cuando hay tres o más.
Manejo de NULL
Cuando la condición de IF evalúa a NULL, MySQL la trata como falsa y devuelve el tercer argumento:
SELECT
nombre,
telefono_secundario,
IF(telefono_secundario IS NOT NULL, 'Tiene alternativo', 'Solo principal') AS tipo_contacto
FROM clientes
LIMIT 5;| nombre | telefono_secundario | tipo_contacto |
|---|---|---|
| María | NULL | Solo principal |
| Carlos | 612345678 | Tiene alternativo |
| Ana | NULL | Solo principal |
| Pedro | 698765432 | Tiene alternativo |
| Lucía | NULL | Solo principal |
Es importante usar IS NOT NULL explícitamente en la condición. Si escribieras IF(telefono_secundario, ...), MySQL evaluaría el valor del teléfono como booleano, lo que puede dar resultados inesperados con cadenas vacías o valores numéricos.
También puedes usar IF en los propios valores de retorno para manejar NULL en cálculos:
SELECT
nombre,
precio,
descuento,
IF(descuento IS NULL, precio, precio * (1 - descuento / 100)) AS precio_final
FROM productos
LIMIT 4;Si la columna descuento es NULL, el precio final será el precio original. Si tiene un valor, se aplica el descuento. Esto evita que la aritmética con NULL propague nulos al resultado (cualquier operación aritmética con NULL devuelve NULL).
Combinación con otras funciones
IF se integra de forma natural con funciones de cadena, de fecha y matemáticas:
SELECT
CONCAT(nombre, ' ', apellidos) AS empleado,
salario,
IF(salario > 40000,
CONCAT('Bonificación: ', FORMAT(salario * 0.05, 2), ' EUR'),
'Sin bonificación'
) AS bono
FROM empleados
ORDER BY salario DESC;| empleado | salario | bono |
|---|---|---|
| Laura Martínez Díaz | 55000.00 | Bonificación: 2,750.00 EUR |
| Carlos Gómez Ruiz | 48000.00 | Bonificación: 2,400.00 EUR |
| Ana López Torres | 42000.00 | Bonificación: 2,100.00 EUR |
| Pedro Sánchez Mora | 35000.00 | Sin bonificación |
| Daniel Herrera Vega | 32000.00 | Sin bonificación |
| Lucía Fernández Gil | 28000.00 | Sin bonificación |
Aquí IF decide si el empleado tiene bonificación y, en caso afirmativo, CONCAT y FORMAT construyen un mensaje con el importe formateado. Este tipo de combinación es habitual en consultas que generan reportes listos para presentar.
Otra combinación útil es IF con DATEDIFF para clasificar la antigüedad de pedidos:
SELECT
id,
fecha_pedido,
estado,
IF(DATEDIFF(CURDATE(), fecha_pedido) > 60,
'Requiere revisión',
'Reciente'
) AS antiguedad
FROM pedidos
WHERE estado IN ('pendiente', 'procesando')
ORDER BY fecha_pedido;| id | fecha_pedido | estado | antiguedad |
|---|---|---|---|
| 12 | 2025-12-01 10:30:00 | procesando | Requiere revisión |
| 13 | 2025-12-03 14:00:00 | pendiente | Requiere revisión |
| 14 | 2025-12-05 11:15:00 | pendiente | Requiere revisión |
| 15 | 2025-12-08 09:30:00 | pendiente | Requiere revisión |
| 18 | 2025-12-15 10:00:00 | pendiente | Requiere revisión |
| 24 | 2026-01-05 12:00:00 | pendiente | Reciente |
DATEDIFF calcula los días transcurridos desde la fecha del pedido hasta hoy, y IF clasifica el resultado. Los pedidos que llevan más de 60 días sin resolverse se marcan para revisión, lo que permite al equipo de operaciones priorizar su atención.
En el siguiente artículo veremos IFNULL para manejar valores nulos de forma sencilla.
Escrito por Eduardo Lázaro
