Cláusula HAVING

La cláusula HAVING permite hacer selecciones en situaciones en las que no es posible usar WHERE. Veamos un ejemplo completo:

mysql> CREATE TABLE muestras (
    -> ciudad VARCHAR(40), 
    -> fecha DATE, 
    -> temperatura TINYINT);
Query OK, 0 rows affected (0.25 sec)

mysql> mysql> INSERT INTO muestras (ciudad,fecha,temperatura) VALUES
    -> ('Madrid', '2005-03-17', 23),
    -> ('París', '2005-03-17', 16),
    -> ('Berlín', '2005-03-17', 15),
    -> ('Madrid', '2005-03-18', 25),
    -> ('Madrid', '2005-03-19', 24),
    -> ('Berlín', '2005-03-19', 18);
Query OK, 6 rows affected (0.03 sec)
Records: 6  Duplicates: 0  Warnings: 0

mysql> SELECT ciudad, MAX(temperatura) FROM muestras
    -> GROUP BY ciudad HAVING MAX(temperatura)>16;
+--------+------------------+
| ciudad | MAX(temperatura) |
+--------+------------------+
| Berlín |               18 |
| Madrid |               25 |
+--------+------------------+
2 rows in set (0.00 sec)

mysql>

La cláusula WHERE no se puede aplicar a columnas calculadas mediante funciones de reunión, como en este ejemplo.

Ordenar resultados

Además, podemos añadir una cláusula de orden ORDER BY para obtener resultados ordenados por la columna que queramos:

mysql> SELECT * FROM gente ORDER BY fecha;
+----------+------------+
| nombre   | fecha      |
+----------+------------+
| Mengano  | 1978-06-15 |
| Pimplano | 1978-06-15 |
| Fulano   | 1985-04-12 |
| Frutano  | 1985-04-12 |
| Pegano   | 1993-02-10 |
| Tulano   | 2001-12-02 |
+----------+------------+
6 rows in set (0.02 sec)

mysql>

Existe una opción para esta cláusula para elegir el orden, ascendente o descendente. Se puede añadir a continuación ASC o DESC, respectivamente. Por defecto se usa el orden ascendente, de modo que el modificador ASC es opcional.

mysql> SELECT * FROM gente ORDER BY fecha DESC;
+----------+------------+
| nombre   | fecha      |
+----------+------------+
| Tulano   | 2001-12-02 |
| Pegano   | 1993-02-10 |
| Fulano   | 1985-04-12 |
| Frutano  | 1985-04-12 |
| Mengano  | 1978-06-15 |
| Pimplano | 1978-06-15 |
+----------+------------+
6 rows in set (0.00 sec)

mysql>

Limitar el número de filas de salida

Por último, la cláusula LIMIT permite limitar el número de filas devueltas:

mysql> SELECT * FROM gente LIMIT 3;
+---------+------------+
| nombre  | fecha      |
+---------+------------+
| Fulano  | 1985-04-12 |
| Mengano | 1978-06-15 |
| Tulano  | 2001-12-02 |
+---------+------------+
3 rows in set (0.19 sec)

mysql>

Esta cláusula se suele usar para obtener filas por grupos, y no sobrecargar demasiado al servidor, o a la aplicación que recibe los resultados. Para poder hacer esto la clásula LIMIT admite dos parámetros. Cuando se usan los dos, el primero indica el número de la primera fila a recuperar, y el segundo el número de filas a recuperar. Podemos, por ejemplo, recuperar las filas de dos en dos:

mysql> Select * from gente limit 0,2;
+---------+------------+
| nombre  | fecha      |
+---------+------------+
| Fulano  | 1985-04-12 |
| Mengano | 1978-06-15 |
+---------+------------+
2 rows in set (0.00 sec)

mysql> Select * from gente limit 2,2;
+--------+------------+
| nombre | fecha      |
+--------+------------+
| Tulano | 2001-12-02 |
| Pegano | 1993-02-10 |
+--------+------------+
2 rows in set (0.02 sec)

mysql> Select * from gente limit 4,2;
+----------+------------+
| nombre   | fecha      |
+----------+------------+
| Pimplano | 1978-06-15 |
| Frutano  | 1985-04-12 |
+----------+------------+
2 rows in set (0.00 sec)

mysql> Select * from gente limit 6,2;
Empty set (0.00 sec)

mysql>

Comentarios de los usuarios (2)

GERARDO SANCHEZ
2016-11-28 15:49:10

la definicion de HAVING no es correcta, la clausula HAVING se usa sobre campos agrupados por GROUP BY, por ejemplo:

SELECT departamento, SUM(sueldo) FROM empleados GROUP BY departamento HAVING SUM(sueldo) > 1000

Este query retorna una lista de cada departamento y el sueldo maximo que se paga en ese departamento SI ESTE SUELDO ES MAYOR A 1000

Es decir, dicho más simple, HAVING es un WHERE pero sobre los campos agrupados por GROUP BY

Salvador Pozo
2016-12-09 12:00:45

Hola:

La definición tal vez sea incompleta, pero no incorrecta.

HAVING se puede usar sobre consultas agrupadas, tanto si la condición se aplica a campos agrupados o no. Es decir, la consulta debe contener "GROUP BY", pero la cláusula HAVING se puede aplicar a cualquiera de los campos de la consulta. Tanto en mi ejemplo como en el tuyo se aplica a campos distintos del indicado en GROUP BY.

En tu ejemplo se agrupa por "departamento", y se aplica HAVING sobre SUM(sueldo). En el mío se agrupa por "ciudad" y se aplica HAVING sobre MAX(temperatura).

En alguna próxima actualización completaré la definición.

Gracias.