web-dev-qa-db-fra.com

Où vs ayant

Pourquoi devez-vous placer les colonnes que vous créez vous-même (par exemple select 1 as "number") après HAVING et non pas WHERE dans MySQL?

Et y at-il des inconvénients au lieu de faire WHERE 1 (écrire la définition entière au lieu d’un nom de colonne)?

238
baloo

Pourquoi est-il nécessaire de placer les colonnes que vous créez vous-même (par exemple, "sélectionnez 1 comme nombre") après HAVING et non WHERE dans MySQL?

WHERE est appliqué avant GROUP BY, HAVING est appliqué après (et peut filtrer sur des agrégats).

En général, vous pouvez référencer des alias dans aucune de ces clauses, mais MySQL permet de référencer des alias de niveau SELECT dans GROUP BY, ORDER BY et HAVING.

Et y at-il des inconvénients au lieu de "WHERE 1" (écrire la définition entière au lieu d’un nom de colonne)

Si votre expression calculée ne contient aucun agrégat, son insertion dans la clause WHERE sera probablement plus efficace.

311
Quassnoi

Toutes les réponses sur n'ont pas touché le point clé.

Supposons que nous ayons une table:

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

Et avoir 10 lignes avec id et valeur de 1 à 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);

Essayez les 2 requêtes suivantes:

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

Vous obtiendrez exactement les mêmes résultats, vous constaterez que la clause HAVING peut fonctionner sans la clause GROUP BY.

Voici la différence:

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

Erreur n ° 1054 - Colonne inconnue 'v' dans 'clause Where'

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

La clause WHERE permet à une condition d'utiliser n'importe quelle colonne de la table, mais elle ne peut pas utiliser d'alias ni de fonctions d'agrégat. La clause HAVING permet à une condition d'utiliser une colonne sélectionnée (!), Un alias ou une fonction d'agrégat.

En effet, la clause WHERE filtre les données avant la sélection, mais la clause HAVING filtre les données résultantes après la sélection.

Donc, mettre les conditions dans la clause WHERE sera plus efficace si vous avez beaucoup de lignes dans une table.

Essayez EXPLAIN pour voir la différence clé:

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 |
+----+-------------+-------+-------+---------------+-------+---------+------+------+-------------+

Vous pouvez voir où WHERE ou HAVING utilise index, mais les lignes sont différentes.

265
Fishdrowned

La principale différence est que WHERE ne peut pas être utilisé sur un élément groupé (tel que SUM(number)) alors que HAVING peut.

La raison en est que la WHERE est terminée avant le groupement et HAVING est terminée après le regroupement est effectué.

61
David Brunelle

HAVING est utilisé pour filtrer les agrégations dans votre GROUP BY.

Par exemple, pour vérifier les noms en double:

SELECT Name FROM Usernames
GROUP BY Name
HAVING COUNT(*) > 1
39
Kevin McKelvin

Ces 2 seront identiques au début car les deux sont utilisés pour parler d’une condition de filtrage des données. Bien que nous puissions utiliser "avoir" à la place de "où" dans tous les cas, il est parfois impossible d’utiliser "où" au lieu de "avoir". En effet, dans une requête de sélection, "où" filtre les données avant "sélectionner" et "ayant" filtre les données après "sélectionner". Ainsi, lorsque nous utilisons des noms d’alias qui ne figurent pas réellement dans la base de données, "où" ne peut pas les identifier mais "avoir" peut.

Ex: laissez la table Student contenir id_étudiant, nom, date de naissance, adresse. Date de supposition est de type date.

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.*/
7
Nuwantha

filtre avant que les données ne soient regroupées et AYANT filtre après que les données soient groupées. Cette distinction est importante; les lignes qui sont éliminées par une clause ne seront pas incluses dans le groupe. Cela pourrait modifier les valeurs calculées, ce qui pourrait affecter les groupes filtrés en fonction de l'utilisation de ces valeurs dans la clause HAVING.

Extrait de: Forta, Ben. "Sams Teach Yourself SQL en 10 minutes (4ème édition) (Sams Teach Yourself ...).".

2
snr

Avoir n'est utilisé qu'avec l'agrégation mais où avec les instructions de non agrégation Si vous avez où Word l'a placé avant l'agrégation (group by)

1
Hos Mercury