Contenido de esta guía
Qué hacen
LEAST(a, b, c) devuelve el menor de sus argumentos y GREATEST(a, b, c) devuelve el mayor. A diferencia de MIN() y MAX() como agregaciones, comparan expresiones dentro de una misma fila en lugar de resumir varias filas.
Ejemplo: limitar un valor a un máximo
Imagina que una promoción no puede aplicar más de 30 euros de descuento aunque el cálculo bruto sea mayor.
WITH ofertas(nombre, descuento_calculado) AS (
VALUES ('A', 12), ('B', 35), ('C', 27)
)
SELECT
nombre,
LEAST(descuento_calculado, 30) AS descuento_aplicado
FROM ofertas
ORDER BY nombre;| nombre | descuento_aplicado |
|---|---|
| A | 12 |
| B | 30 |
| C | 27 |
SQLite usa min() y max() con varios argumentos
SQLite no expone LEAST/GREATEST con esos nombres. Sus funciones escalares min(X,Y,...) y max(X,Y,...) cumplen el papel equivalente cuando reciben dos o más argumentos.
WITH ofertas(nombre, descuento_calculado) AS (
VALUES ('A', 12), ('B', 35), ('C', 27)
)
SELECT
nombre,
min(descuento_calculado, 30) AS descuento_aplicado
FROM ofertas
ORDER BY nombre;La diferencia importante: NULL
No copies la intuición de un motor a otro. PostgreSQL y SQL Server documentan que LEAST/GREATEST ignoran argumentos NULL cuando existe al menos un valor no nulo. MySQL documenta que GREATEST() devuelve NULL si cualquier argumento es NULL; SQLite también hace que su max(X,Y,...) multargumento devuelva NULL si algún argumento es nulo.
Consecuencia: GREATEST(10, NULL, 20) no es portable como expresión semánticamente idéntica. Si el tratamiento de nulos importa, normalízalos de forma explícita con CASE o COALESCE según la pregunta real.
Los tipos también importan
Los argumentos deben poder compararse bajo las reglas del motor. Mezclar texto y números puede activar conversiones implícitas o producir un error. Para una consulta mantenible, procura comparar valores del mismo dominio y usa CAST cuando la conversión sea deliberada.
Cuándo usar LEAST/GREATEST y cuándo MIN/MAX
| Pregunta | Herramienta |
|---|---|
| ¿Cuál de estas tres columnas es la fecha más reciente de esta fila? | GREATEST(col1, col2, col3) |
| ¿Cuál es el precio más alto entre todas las filas? | MAX(precio) |
| ¿Quiero imponer un límite superior por fila? | LEAST(valor, limite) |
| ¿Quiero resumir un grupo? | MIN() / MAX() agregados |
Práctica: acota una puntuación
Mantén la puntuación entre 0 y 100
En motores con LEAST/GREATEST, limita cada valor primero a un mínimo de 0 y luego a un máximo de 100.
GREATEST(valor, 0) evita valores menores que cero.LEAST(..., 100).min(max(valor, 0), 100).Solución razonada
SELECT LEAST(GREATEST(puntuacion, 0), 100) AS puntuacion_acotada
FROM resultados;La expresión interior corrige el límite inferior y la exterior aplica el superior. Si tus datos admiten NULL, decide explícitamente qué debe ocurrir antes de usar esta forma entre motores.
Qué debes recordar
LEASTyGREATESTcomparan varias expresiones de una fila.- No son lo mismo que
MIN/MAXagregados. - SQLite utiliza
min()/max()escalares con varios argumentos. - El tratamiento de
NULLdifiere entre motores; no lo presupongas. - Mantén tipos comparables y convierte de forma explícita cuando sea necesario.