2010-05-25 9 views
196

¿Por qué necesita colocar columnas creadas usted mismo (por ejemplo select 1 as "number") después de HAVING y no WHERE en MySQL?DONDE vs TIENE

¿Y hay alguna desventaja en lugar de hacer WHERE 1 (escribir la definición completa en lugar de un nombre de columna)?

Respuesta

270

Por qué es que hay que colocar columnas que crea usted mismo (por ejemplo, "seleccione 1 como número") después de tener y no donde en MySQL?

WHERE se aplica antes de GROUP BY, HAVING se aplica después (y puede filtrar en agregados).

En general, se puede hacer referencia a los alias en ninguna de estas cláusulas, pero MySQL permite referenciar SELECT alias nivel en GROUP BY, ORDER BY y HAVING.

Y ¿hay desventajas en lugar de hacer "WHERE 1" (escribir toda la definición en lugar de un nombre de columna)

Si su expresión calculada no contiene agregados, poniéndolo en el WHERE cláusula probablemente será más eficiente.

55

La principal diferencia es que WHERE no se puede utilizar en el elemento agrupado (como SUM(number)) mientras que HAVING puede.

La razón es la WHERE se hace antes la agrupación y HAVING se hace después se realiza la agrupación.

38

HAVING se utiliza para filtrar agregaciones en su GROUP BY.

Por ejemplo, para comprobar si hay nombres duplicados:

SELECT Name FROM Usernames 
GROUP BY Name 
HAVING COUNT(*) > 1 
+1

Es cierto para algunos existentes. Todavía puede poner todo su 'Dónde' en la cláusula having. –

+0

También vea http://stackoverflow.com/questions/2905292/where-vs-having#comment48406726_18710763 – Pacerier

211

todas las respuestas a no golpear el punto clave.

Asumamos que tenemos una 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 

y tiene 10 filas con ambos ID y el 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 preguntas:

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 - Desconocido columna 'v' en 'cláusula where'

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

cláusula WHERE requiere una condición para ser una columna de una tabla, pero La cláusula HAVING puede usar columna o alias.

Esto se debe a que la cláusula WHERE filtra los datos antes de seleccionarlos, pero HAVING cláusula filtra los datos después de seleccionarlos.

Por lo tanto, ponga las condiciones en la cláusula WHERE será más eficiente si tiene muchas filas en una tabla.

Trate de explicarle a 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 | 
+----+-------------+-------+-------+---------------+-------+---------+------+------+-------------+ 

se puede ver ya sea WHERE o HAVING índice de usos, pero las filas son diferentes.

+22

¡Agradezco que haya mencionado EXPLICAR! – paiego

+0

Debido a que TIENE filtros de cláusula de datos después de seleccionar, la cláusula WHERE será más efectiva. Entonces, si esto es cierto, ¿cuándo debemos usar HAVING en lugar de WHERE? – grep

+5

@grep En caso de que tenga que filtrar datos después de seleccionar, necesita la cláusula HAVING, generalmente la usamos con la cláusula GROUP BY, por ejemplo: 'SELECT value, COUNT (*) frequency FROM table GROUP GROUP value HAVING frequency> 10' – Fishdrowned

4

Estos 2 se sentirán igual que los primeros que se usan para decir sobre una condición para filtrar datos. Aunque podemos usar 'having' en lugar de 'where' en cualquier caso, hay casos en los que no podemos usar 'where' en lugar de 'having'. Esto se debe a que en una consulta de selección, 'donde' filtra los datos antes de 'seleccionar' mientras 'tiene' datos de filtro 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' puede.

Ejemplo: deje que la tabla Estudiante contenga el nombre del alumno, el nombre, el cumpleaños, la dirección. Suponga que el cumpleaños es del 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.*/ 
+0

Este ejemplo de la vida real aclara completamente la diferencia entre 'WHERE 'y' HAVING'. –

1

Habiendo sólo se utiliza con la agregación pero donde con declaraciones no agregación Si tienes donde la palabra la puso antes de la agregación (grupo de)

0
  • Un DONDE se utiliza cláusula es filtrar los registros de un resultado. El filtro se produce antes de que se realicen agrupaciones.
  • A HAVING cláusula se utiliza para filtrar valores de un grupo. Antes de que vaya más allá, revisemos el formato de una declaración de SQL. Es

    SELECT SalesOrderID, SUM (* PrecioUnidad OrderQty) AS TotalPrice DE Sales.SalesOrderDetail DONDE LineTotal> 100 GROUP BY SalesOrderID HAVING SUM (* PrecioUnidad OrderQty)> 10000

Clave point, que también es la principal diferencia entre WHERE y la cláusula HAVING en SQL es que, la condición especificada en la cláusula WHERE se usa mientras se extraen datos (filas) de la tabla, y los datos que no pasan la condición no se recuperarán en el conjunto de resultados , por otro lado, la cláusula HAVING se usa luego para filtrar datos resumidos o datos agrupados.

En resumen, si tanto DONDE y TIENE cláusula se utiliza en una consulta SELECT con función de agregado o cláusula GROUP BY, se ejecutará antes de la cláusula HAVING.

0

DONDE filtros antes se agrupan los datos, y TENER filtros después se agrupa datos. Esta es una distinción importante; filas que son eliminadas por un DONDE cláusula no se incluirá en el grupo. Este podría cambiar los valores calculados que a su vez podrían afectar qué grupos se filtran según el uso de esos valores en la cláusula HAVING .

Extracto De: Forta, Ben. "Sams Te enseña a ti mismo SQL en 10 minutos (4ta Edición ) (Sams Teach Yourself ...).".

Cuestiones relacionadas