Respuestas:
¿Por qué es necesario colocar columnas que usted mismo cree (por ejemplo, "seleccione 1 como número") después de TENER y NO DÓNDE en MySQL?
WHERE
se aplica antes GROUP BY
, HAVING
se aplica después (y puede filtrar en agregados).
En general, puede hacer referencia a alias en ninguna de estas cláusulas, pero MySQL
permite hacer referencia a SELECT
alias de nivel en GROUP BY
, ORDER BY
y HAVING
.
¿Y hay inconvenientes en lugar de hacer "WHERE 1" (escribir la definición completa en lugar del nombre de una columna)
Si su expresión calculada no contiene ningún agregado, ponerlo en la WHERE
cláusula probablemente será más eficiente.
Todas las demás respuestas a esta pregunta no dieron en el punto clave.
Supongamos que tenemos una mesa:
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
Y tenga 10 filas con id y valor 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);
Pruebe las siguientes 2 consultas:
SELECT `value` v FROM `table` WHERE `value`>5; -- Get 5 rows
SELECT `value` v FROM `table` HAVING `value`>5; -- Get 5 rows
Obtendrá exactamente los mismos resultados, puede ver que la cláusula HAVING puede funcionar sin la cláusula GROUP BY.
Aquí está la diferencia:
SELECT `value` v FROM `table` WHERE `v`>5;
Error # 1054 - Columna desconocida 'v' en 'cláusula where'
SELECT `value` v FROM `table` HAVING `v`>5; -- Get 5 rows
La cláusula WHERE permite que una condición use cualquier columna de tabla, pero no puede usar alias o funciones agregadas. La cláusula HAVING permite que una condición use una columna (!) Seleccionada, un alias o una función agregada.
Esto se debe a que la cláusula WHERE filtra los datos antes de la selección, pero la cláusula HAVING filtra los datos resultantes después de la selección.
Por lo tanto, ponga las condiciones en la cláusula WHERE será más eficiente si tiene muchas filas en una tabla.
Intente EXPLICAR para ver la diferencia clave:
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 |
+----+-------------+-------+-------+---------------+-------+---------+------+------+-------------+
Puede ver WHERE o HAVING usa index, pero las filas son diferentes.
SELECT value, COUNT(*) frequency FROM table GROUP BY value HAVING frequency > 10
...HAVING clause can use both column and alias.
a ...HAVING clause can use either column or alias.
y el cambio ...WHERE clause will be more effective
a...WHERE clause will be more efficient
La principal diferencia es que WHERE
no se puede usar en elementos agrupados (como SUM(number)
), mientras que HAVING
sí.
La razón es que WHERE
se realiza antes de la agrupación y HAVING
se realiza después de que se realiza la agrupación.
HAVING
se utiliza para filtrar agregaciones en su GROUP BY
.
Por ejemplo, para verificar nombres duplicados:
SELECT Name FROM Usernames
GROUP BY Name
HAVING COUNT(*) > 1
Estos 2 se sentirán igual que los primeros, ya que ambos se usan para decir acerca de una condición para filtrar datos. Aunque podemos usar 'tener' en lugar de 'dónde' en cualquier caso, hay casos en los que no podemos usar 'dónde' en lugar de 'tener'. Esto se debe a que en una consulta de selección, 'donde' filtra datos antes de 'seleccionar' mientras 'tiene' filtrar datos después de 'seleccionar'. Entonces, cuando usamos nombres de alias que no están realmente en la base de datos, 'where' no puede identificarlos pero 'having' sí.
Ej: deje que la tabla Alumno contenga student_id, nombre, cumpleaños, dirección. Asumir que el cumpleaños es de tipo fecha.
SELECT * FROM Student WHERE YEAR(birthday)>1993; /*this will work as birthday is in database.if we use having in place of where too this will work*/
SELECT student_id,(YEAR(CurDate())-YEAR(birthday)) AS Age FROM Student HAVING Age>20;
/*this will not work if we use ‘where’ here, ‘where’ don’t know about age as age is defined in select part.*/
WHERE
y HAVING
.
WHERE filtra antes de que se agrupen los datos y HAVING filtra después de que se agrupan los datos. Esta es una distinción importante; las filas que se eliminan mediante una cláusula WHERE no se incluirán en el grupo. Esto podría cambiar los valores calculados que, a su vez (= como resultado) podrían afectar qué grupos se filtran en función del uso de esos valores en la cláusula HAVING .
Y continúa
TENER es tan similar a DONDE que la mayoría de los DBMS los tratan como lo mismo si no se especifica GROUP BY . Sin embargo, debe hacer esa distinción usted mismo. Use HAVING solo junto con las cláusulas GROUP BY . Use WHERE para el filtrado de nivel de fila estándar.
Extracto de: Forta, Ben. "Sams Teach Yourself SQL en 10 minutos (5ª edición) (Sams Teach Yourself ...)".
Tener solo se usa con agregación, pero donde con declaraciones de no agregación Si tiene donde la palabra lo pone antes de la agregación (agrupar por)