MIN
La función MIN devuelve el valor más pequeño de un conjunto de valores. Aunque parece una función trivial, tiene usos muy variados: encontrar el producto más barato, la fecha del primer pedido, el empleado con menor antigüedad o incluso el primer valor alfabéticamente en una columna de texto. Al igual que las demás funciones de agregación, MIN ignora los valores NULL.
Sintaxis
MIN(expresion)MIN acepta una columna o cualquier expresión que devuelva un valor comparable. Funciona con números, fechas, cadenas de texto y cualquier tipo de dato que MySQL pueda ordenar. Cuando se usa sin GROUP BY, devuelve el valor mínimo de toda la tabla. Con GROUP BY, devuelve el mínimo de cada grupo.
Comportamiento básico
Para encontrar el producto más barato del catálogo:
SELECT
MIN(precio) AS precio_minimo,
MAX(precio) AS precio_maximo,
MAX(precio) - MIN(precio) AS rango_precios
FROM productos;| precio_minimo | precio_maximo | rango_precios |
|---|---|---|
| 9.99 | 1899.99 | 1890.00 |
El rango de precios (la diferencia entre el máximo y el mínimo) te da una idea de la dispersión del catálogo. Un rango de 1890 euros indica que el inventario abarca desde accesorios económicos hasta equipos de alta gama.
MIN también funciona con fechas. Para saber cuándo se registró el primer pedido:
SELECT
MIN(fecha_pedido) AS primer_pedido,
MAX(fecha_pedido) AS ultimo_pedido,
DATEDIFF(MAX(fecha_pedido), MIN(fecha_pedido)) AS dias_operacion
FROM pedidos;| primer_pedido | ultimo_pedido | dias_operacion |
|---|---|---|
| 2024-03-15 | 2026-02-10 | 697 |
La tienda lleva 697 días de operación, desde marzo de 2024 hasta febrero de 2026.
Caso práctico: precio mínimo por categoría
Con GROUP BY puedes encontrar el producto más barato de cada categoría:
SELECT
c.nombre AS categoria,
MIN(p.precio) AS precio_minimo,
ROUND(AVG(p.precio), 2) AS precio_medio
FROM productos p
JOIN categorias c ON p.categoria_id = c.id
GROUP BY c.nombre
ORDER BY precio_minimo ASC;| categoria | precio_minimo | precio_medio |
|---|---|---|
| Accesorios electrónicos | 9.99 | 42.85 |
| Libros | 14.99 | 22.50 |
| Ropa hombre | 19.99 | 59.99 |
| Ropa mujer | 24.99 | 64.99 |
| Hogar | 29.99 | 124.80 |
| Deportes | 39.99 | 189.99 |
| Smartphones | 299.00 | 785.42 |
| Portátiles | 799.00 | 1245.50 |
Observa que en algunas categorías el precio mínimo está muy lejos de la media. Los accesorios van desde 9.99 hasta precios más altos, mientras que los portátiles empiezan en 799 euros.
Caso práctico: encontrar la fila con el valor mínimo
Un problema clásico: no solo quieres saber cuál es el precio mínimo, sino qué producto tiene ese precio. MIN devuelve solo el valor, no la fila completa. Hay varias formas de resolverlo.
La más directa es usar una subconsulta:
SELECT nombre, precio
FROM productos
WHERE precio = (SELECT MIN(precio) FROM productos);| nombre | precio |
|---|---|
| Cable USB-C a Lightning | 9.99 |
Si quieres el producto más barato de cada categoría, necesitas una subconsulta correlacionada o un JOIN:
SELECT p.nombre, c.nombre AS categoria, p.precio
FROM productos p
JOIN categorias c ON p.categoria_id = c.id
WHERE p.precio = (
SELECT MIN(p2.precio)
FROM productos p2
WHERE p2.categoria_id = p.categoria_id
)
ORDER BY p.precio;| nombre | categoria | precio |
|---|---|---|
| Cable USB-C a Lightning | Accesorios electrónicos | 9.99 |
| El Quijote edición bolsillo | Libros | 14.99 |
| Camiseta algodón básica | Ropa hombre | 19.99 |
| Blusa estampada | Ropa mujer | 24.99 |
| Vela aromática lavanda | Hogar | 29.99 |
| Banda de resistencia | Deportes | 39.99 |
| Xiaomi Redmi Note 13 | Smartphones | 299.00 |
| Acer Aspire 5 | Portátiles | 799.00 |
Otra alternativa moderna es usar la función de ventana ROW_NUMBER:
SELECT nombre, categoria, precio
FROM (
SELECT
p.nombre,
c.nombre AS categoria,
p.precio,
ROW_NUMBER() OVER (PARTITION BY c.id ORDER BY p.precio ASC) AS rn
FROM productos p
JOIN categorias c ON p.categoria_id = c.id
) ranked
WHERE rn = 1
ORDER BY precio;Este enfoque es más eficiente cuando tienes muchas categorías porque evita ejecutar una subconsulta por cada fila.
Caso práctico: MIN con cadenas de texto
MIN aplicado a cadenas de texto devuelve el primer valor en orden alfabético según la intercalación (collation) de la columna:
SELECT
MIN(nombre) AS primer_nombre_alfa,
MAX(nombre) AS ultimo_nombre_alfa
FROM clientes;| primer_nombre_alfa | ultimo_nombre_alfa |
|---|---|
| Alberto | Víctor |
Esto es útil para verificar rangos de datos o para consultas donde necesitas el primer o último valor lexicográfico de un grupo.
Manejo de NULL
MIN ignora los valores NULL. Si todas las filas de un grupo tienen NULL, el resultado es NULL:
SELECT
MIN(descuento) AS menor_descuento,
MIN(IFNULL(descuento, 0)) AS menor_con_ceros
FROM productos;| menor_descuento | menor_con_ceros |
|---|---|
| 5.00 | 0 |
Sin IFNULL, el menor descuento registrado es 5.00, porque los productos sin descuento (NULL) se ignoran. Con IFNULL, los NULL se convierten en cero y el mínimo pasa a ser 0. Elige uno u otro según el contexto de tu análisis.
Combinación con otras funciones
MIN se combina frecuentemente con otras funciones de agregación para crear resúmenes estadísticos completos:
SELECT
c.nombre AS categoria,
COUNT(*) AS productos,
MIN(p.precio) AS minimo,
ROUND(AVG(p.precio), 2) AS media,
MAX(p.precio) AS maximo,
MAX(p.precio) - MIN(p.precio) AS rango
FROM productos p
JOIN categorias c ON p.categoria_id = c.id
GROUP BY c.nombre
ORDER BY rango DESC;| categoria | productos | minimo | media | maximo | rango |
|---|---|---|---|---|---|
| Portátiles | 8 | 799.00 | 1245.50 | 1899.99 | 1100.99 |
| Smartphones | 12 | 299.00 | 785.42 | 1299.99 | 1000.99 |
| Deportes | 4 | 39.99 | 189.99 | 449.99 | 410.00 |
| Hogar | 5 | 29.99 | 124.80 | 299.99 | 270.00 |
El rango (diferencia entre máximo y mínimo) indica cuán variados son los precios dentro de cada categoría. Un rango alto sugiere que la categoría cubre diferentes segmentos de mercado.
También puedes usar MIN en HAVING para filtrar grupos:
SELECT c.nombre AS categoria
FROM productos p
JOIN categorias c ON p.categoria_id = c.id
GROUP BY c.nombre
HAVING MIN(p.precio) > 100;Esta consulta encuentra las categorías donde incluso el producto más barato cuesta más de 100 euros.
Practica con MIN
Usa el editor para encontrar valores mínimos:
En el siguiente artículo veremos MAX para obtener el valor máximo.
Escrito por Eduardo Lázaro
