Dans les requêtes SQL, nous utilisons la clause Group by pour appliquer des fonctions d'agrégation.
C'est en fait une très mauvaise chose à faire à mon humble avis, et ce n'est pas pris en charge dans la plupart des autres plates-formes de bases de données.
Les raisons pour lesquelles les gens le font:
Les raisons pour lesquelles c'est mauvais:
ce n'est pas auto-documenté - quelqu'un va devoir analyser la liste SELECT pour comprendre le regroupement. Ce serait en fait un peu plus clair dans SQL Server, qui ne prend pas en charge le regroupement cowboy qui sait ce qui se passera comme le fait MySQL.
c'est fragile - quelqu'un entre et modifie la liste SELECT parce que les utilisateurs professionnels voulaient une sortie de rapport différente, et maintenant votre sortie est un gâchis. Si vous aviez utilisé des noms de colonne dans le GROUP BY, l'ordre dans la liste SELECT ne serait pas pertinent.
SQL Server prend en charge ORDER BY [ordinal]; voici quelques arguments parallèles contre son utilisation:
MySQL vous permet de faire GROUP BY
avec des alias ( Problèmes avec les alias de colonne ). Ce serait bien mieux que de faire GROUP BY
avec des nombres.
column number
dans les diagrammes SQL . Une ligne dit: Trie le résultat par le numéro de colonne donné ou par une expression. Si l'expression est un seul paramètre, la valeur est interprétée comme un numéro de colonne. Les numéros de colonne négatifs inversent l'ordre de tri.Google a de nombreux exemples d'utilisation et pourquoi beaucoup ont cessé de l'utiliser.
Pour être honnête avec vous, je n'ai pas utilisé de numéros de colonne pour ORDER BY
et GROUP BY
depuis 1996 (je faisais du développement Oracle PL/SQL à l'époque). L'utilisation des numéros de colonne est vraiment pour les anciens et la compatibilité descendante permet à ces développeurs d'utiliser MySQL et d'autres SGBDR qui le permettent encore.
Considérez le cas ci-dessous:
+------------+--------------+-----------+
| date | services | downloads |
+------------+--------------+-----------+
| 2016-05-31 | Apps | 1 |
| 2016-05-31 | Applications | 1 |
| 2016-05-31 | Applications | 1 |
| 2016-05-31 | Apps | 1 |
| 2016-05-31 | Videos | 1 |
| 2016-05-31 | Videos | 1 |
| 2016-06-01 | Apps | 3 |
| 2016-06-01 | Applications | 4 |
| 2016-06-01 | Videos | 2 |
| 2016-06-01 | Apps | 2 |
+------------+--------------+-----------+
Vous devez connaître le nombre de téléchargements par service et par jour en considérant les applications et applications comme le même service. Regroupement par date, services
entraînerait que Apps
et Applications
seraient considérés comme des services distincts.
Dans ce cas, la requête serait:
select date, services, sum(downloads) as downloads
from test.zvijay_test
group by date,services
Et sortie:
+------------+--------------+-----------+
| date | services | downloads |
+------------+--------------+-----------+
| 2016-05-31 | Applications | 2 |
| 2016-05-31 | Apps | 2 |
| 2016-05-31 | Videos | 2 |
| 2016-06-01 | Applications | 4 |
| 2016-06-01 | Apps | 5 |
| 2016-06-01 | Videos | 2 |
+------------+--------------+-----------+
Mais ce n'est pas ce que vous voulez, car les applications et les applications à regrouper sont obligatoires. Alors, que pouvons-nous faire?
Une façon consiste à remplacer Apps
par Applications
en utilisant une expression CASE
ou la fonction IF
, puis en les regroupant sur les services comme suit:
select
date,
if(services='Apps','Applications',services) as services,
sum(downloads) as downloads
from test.zvijay_test
group by date,services
Mais cela regroupe toujours les services considérant Apps
et Applications
comme des services différents et donne la même sortie que précédemment:
+------------+--------------+-----------+
| date | services | downloads |
+------------+--------------+-----------+
| 2016-05-31 | Applications | 2 |
| 2016-05-31 | Applications | 2 |
| 2016-05-31 | Videos | 2 |
| 2016-06-01 | Applications | 4 |
| 2016-06-01 | Applications | 5 |
| 2016-06-01 | Videos | 2 |
+------------+--------------+-----------+
Le regroupement sur un numéro de colonne vous permet de regrouper les données sur une colonne aliasée.
select
date,
if(services='Apps','Applications',services) as services,
sum(downloads) as downloads
from test.zvijay_test
group by date,2;
Et vous donnant ainsi la sortie souhaitée comme ci-dessous:
+------------+--------------+-----------+
| date | services | downloads |
+------------+--------------+-----------+
| 2016-05-31 | Applications | 4 |
| 2016-05-31 | Videos | 2 |
| 2016-06-01 | Applications | 9 |
| 2016-06-01 | Videos | 2 |
+------------+--------------+-----------+
J'ai lu à plusieurs reprises que c'est une façon paresseuse d'écrire des requêtes ou de regrouper sur une colonne aliasée ne fonctionne pas dans MySQL, mais c'est la façon de regrouper sur des colonnes aliasées.
Ce n'est pas le moyen préféré d'écrire des requêtes, utilisez-le uniquement lorsque vous avez vraiment besoin de grouper sur une colonne aliasée.
Il n'y a aucune raison valable de l'utiliser. Il s'agit simplement d'un raccourci paresseux spécialement conçu pour rendre difficile pour un développeur pressé de comprendre votre regroupement ou tri plus tard ou pour permettre au code d'échouer lamentablement lorsque quelqu'un change l'ordre des colonnes. Soyez attentif à vos collègues développeurs et ne le faites pas.
Cela fonctionne pour moi. Le code regroupe les lignes jusqu'à 5 groupes.
SELECT
USR.UID,
USR.PROFILENAME,
(
CASE
WHEN MOD(@curRow, 5) = 0 AND @curRow > 0 THEN
@curRow := 0
ELSE
@curRow := @curRow + 1
/*@curRow := 1*/ /*AND @curCode := USR.UID*/
END
) AS sort_by_total
FROM
SS_USR_USERS USR,
(
SELECT
@curRow := 0,
@curCode := ''
) rt
ORDER BY
USR.PROFILENAME,
USR.UID
Le résultat sera le suivant
SELECT dep_month,dep_day_of_week,dep_date,COUNT(*) AS flight_count FROM flights GROUP BY 1,2;
SELECT dep_month,dep_day_of_week,dep_date,COUNT(*) AS flight_count FROM flights GROUP BY 1,2,3;
Considérez les requêtes ci-dessus: Grouper par 1 signifie grouper par la première colonne et grouper par 1,2 signifie grouper par la première et la deuxième colonne et grouper par 1,2,3 signifie grouper par la première deuxième et la troisième colonne. Par exemple:
cette image montre les deux premières colonnes groupées par 1,2 c'est-à-dire qu'elle ne prend pas en compte les différentes valeurs de dep_date pour trouver le compte (pour calculer le compte, toutes les combinaisons distinctes des deux premières colonnes sont prises en considération) tandis que la deuxième requête en résulte -
image. Ici, il considère les trois premières colonnes et il existe différentes valeurs pour trouver le nombre, c'est-à-dire qu'il est regroupé par les trois premières colonnes (pour calculer le nombre, toutes les combinaisons distinctes des trois premières colonnes sont prises en considération).