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)?
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.
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.
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é.
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
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.*/
OÙ 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 OÙ 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 ...).".
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)