Bases de Datos

Cúal es la diferencia entre where y having en mysql?

Autorangel cruz
Publicado
Lectura1 min de lectura

Vayamos directo al grano:

Digamos que tenemos esta tabla:

CREATE TABLE `table` (
 `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
 `value` int(10) unsigned NOT NULL,
 PRIMARY KEY (`id`),
 KEY `value` (`value`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8

Donde tenemos 10 rows, ambos con id y value que van de 1 a 10:

INSERT INTO `table`(`id`, `value`) VALUES (1, 1),(2, 2),(3, 3),(4, 4),(5, 5),(6, 6),(7, 7),(8, 8),(9, 9),(10, 10);

Si hacemos las siguientes querys:

SELECT `value` v FROM `table` WHERE `value`>5; -- Get 5 rows
SELECT `value` v FROM `table` HAVING `value`>5; -- Get 5 rows

Se obtienen exactamente los mismos resultados y como pueden ver, la clausula having puede trabajar sin la clausula GROUP BY

Aquí la diferencia

Si hacemos esto:

SELECT `value` v FROM `table` WHERE `v`>5;

Vamos a obtener:

Error #1054 - Unknown column 'v' in 'where clause'

En cambio:

SELECT `value` v FROM `table` HAVING `v`>5; -- Get 5 rows

La clausula WHERE permite una condición para usar cualquier columna de una tabla pero no permite usar alias o funciones agregadas. La clausula HAVING permite hacer condiciones para usar una columna, alias o una funcion agregada.

Esto se debe a que la clausula WHERE filtra la data antes de ejecutar el select pero HAVING filtra los resultados despues de hacer el select

Usemos EXPLAIN para entender las diferencias:


EXPLAIN SELECT `value` v FROM `table` WHERE `value`>5;
+----+-------------+-------+-------+---------------+-------+---------+------+------+--------------------------+
| id | select_type | table | type  | possible_keys | key   | key_len | ref  | rows | Extra                    |
+----+-------------+-------+-------+---------------+-------+---------+------+------+--------------------------+
|  1 | SIMPLE      | table | range | value         | value | 4       | NULL |    5 | Using where; Using index |
+----+-------------+-------+-------+---------------+-------+---------+------+------+--------------------------+


EXPLAIN SELECT `value` v FROM `table` having `value`>5;
+----+-------------+-------+-------+---------------+-------+---------+------+------+-------------+
| id | select_type | table | type  | possible_keys | key   | key_len | ref  | rows | Extra       |
+----+-------------+-------+-------+---------------+-------+---------+------+------+-------------+
|  1 | SIMPLE      | table | index | NULL          | value | 4       | NULL |   10 | Using index |
+----+-------------+-------+-------+---------------+-------+---------+------+------+-------------+

Cualquiera de los dos (WHERE o HAVING) usan indexpero las rows son diferentes.

Fuente.

Sobre el autor
Angel Cruz

Angel Cruz

Soy desarrollador PHP senior. Casi todo lo que construyo pasa por Laravel, me obsesiona el código que se mantiene y escribo sobre lo que aprendo, con sus trade-offs incluidos.