Certaines personnes se donnent beaucoup de mal pour éviter les clauses GROUP BY et HAVING dans leurs requêtes. Les messages d'erreur sont pointilleux mais ils sont généralement corrects. Les mots clés GROUP BY et HAVING sont essentiels pour un bon reporting SQL.
La principale raison de GROUP BY est de réduire le nombre de lignes, généralement par agrégation. Il produit une seule ligne pour chaque groupement correspondant à partir de l'entrée. Cela vous permet d'effectuer des calculs sophistiqués via SQL ordinaire.
Exemple de fruits :
Nous avons des fruits :
Ce prochain cas nous permet de regarder vers l'avenir. En milieu d'année, quels fruits seront disponibles ? Nous le faisons avec la même requête que ci-dessus, cependant, après l'exécution de la requête, nous vérifions les valeurs de min(fresh_until) en utilisant une clause having. AVOIR est la façon dont vous qualifiez un agrégat.
Toutes les pommes et les raisins seront disponibles en milieu d'année.
La liste des éléments entre SELECT et FROM, la liste cible. peut contenir des non-agrégats et des agrégats. Ces colonnes non agrégées dans la liste cible
doivent figurer dans la clause group by. Le message d'erreur le dit. L'ordre des colonnes dans la clause group by est important. Il détermine comment les agrégats sont regroupés. L'ordre est souvent hiérarchique. Ce que cela signifie pour vos colonnes est votre objectif. Il peut s'agir de fruits, de sources et/ou de produits frais jusqu'à la date.
Exemples de cartes à jouer
Examinons un autre ensemble d'exemples qui illustrent l'extraction d'informations sur les cartes à jouer. Vous pouvez en savoir plus sur les cartes sur Wikipédia Cartes standard.
Supposons que vous distribuiez par programmation six mains de 5 cartes, comme six personnes jouant au poker. Un total de 30 cartes sont utilisées dans cette donne. Ils sont dans une main tableau comme le suivant où les noms des cartes et des costumes sont joints par des tables de recherche. Nous stockons les classements afin de pouvoir trier correctement. Nous utilisons des noms pour l'affichage. Les noms et les rangs ont une relation un à un pour chacune des cartes et des couleurs.
Quel est le nombre de couleurs pour chaque main ? Nous ne nous soucions vraiment que des mains qui ont 3 cartes ou plus de la même couleur. Cela nous dira qui a les meilleures chances d'obtenir une couleur de poker. Notez que bien que GROUP BY semble impliquer ORDER BY, ce n'est pas le cas. ORDER BY doit être explicite.
Et si vous avez mal regroupé votre requête ? Si cette main table n'est pas regroupée par handid, alors vous obtiendrez 30 enregistrements de 6 mains de 5 cartes. Si vous aviez des agrégats, ils seraient regroupés par ligne. Pas très utile.
Si vous regroupez le nom de la carte et n'incluez pas
le nom de la carte en solo dans la liste cible et essayez de trier par nom de carte,
vous recevrez le message d'erreur indiquant qu'il ne devrait pas figurer
l'ordre par clause. La clause order by doit contenir
des éléments de la clause group by.
Cependant, si le nom de la carte est explicitement dans la liste cible,
alors le nom de la carte doit être dans la clause group by et
donc autorisé sur la clause order by.
Si la requête est par couleur, il y aura un minimum de 1 ou un maximum de 4 enregistrements par couleur pour chacune des six mains. Notez que nous trions par rang de costume qui
doit également figurer dans la clause group by. su_name et su_rank ont une relation un à un.
Pour voir la répartition des cartes en mains, Nous devons regrouper par la colonne de classement des cartes. Bien sûr, il y a 4 couleurs de chaque carte, vous ne verrez donc pas une carte dans plus de quatre mains.
Pour jeter un coup d'œil et voir qui détient les as, nous pouvons utiliser la courte requête suivante. Notez qu'il existe une clause WHERE qui est exécutée lors de la collecte des lignes. HAVING est exécuté après la collecte des lignes.
Résumé
Ces exemples sont des moyens simples d'évaluer des entités connues. Expérimentez et utilisez ces règles simples.
- Si une colonne est sur la liste cible et non un agrégat, elle doit être dans une clause GROUP BY.
- Les clauses WHERE se produisent pendant le processus de sélection.
- Les clauses HAVING se produisent une fois les agrégats terminés.
- Seuls les non-agrégats peuvent figurer dans la clause ORDER BY.
- L'ordre de la clause GROUP BY est important.