Mysql
 sql >> Base de données >  >> RDS >> Mysql

Obtenir le nombre d'une catégorie particulière et d'une sous-catégorie bifurquée supplémentaire à l'aide d'une requête SQL

MySQL group by prend en charge WITH ROLLUP qui vous fournira les agrégations plus larges :

Supposons que votre table d'employés ressemble à :

Name, Role, Gender
John, Manager, Male
Susie, Manager, Female
...

Une requête comme celle-ci :

SELECT Gender, Role, COUNT(*)
FROM employee
GROUP BY Gender, Role

Produirait un familier :

Male, Manager, 5
Male, Senior Manager, 2
Male, Employee, 20

etc

Maintenant, si nous ajoutons WITH ROLLUP :

SELECT Gender, Role, COUNT(*)
FROM employee
GROUP BY Gender, Role WITH ROLLUP

Ensuite, MySQL ignorera également le rôle et se groupera uniquement sur le sexe :

Male, Manager, 5
Male, Senior Manager, 2
Male, Employee, 20
Male, NULL, 29

La ligne de rôle NULL est la ligne où tous les rôles sont regroupés et le nombre est le total des hommes. ROLLUP roule de droite à gauche, donc si vous deviez GROUP BY a,b,c,d WITH ROLLUP vous obtiendrez des lignes supplémentaires pour "tous les a,b,c", "tous les a,b" et "tous les a" - l'ordre dans lequel vous placez le genre et le rôle dans votre groupe est donc important !

Enfin, si vous souhaitez modifier un peu les données afin de n'avoir qu'une seule colonne de texte, comme dans votre exemple :

SELECT COALESCE(Role, Gender) as Desc, Ctr
(
  SELECT Gender, Role, COUNT(*) as Ctr
  FROM employee
  GROUP BY Gender, Role WITH ROLLUP
) x --need to use a subquery - see manual
ORDER BY Gender, Role

Mais notez que si vous faites cela, vous rencontrerez un problème car il n'y a plus rien pour distinguer concrètement la rangée masculine "Manager" de la rangée féminine "Manager" ; cela dépend uniquement de l'ordre, et ce n'est pas une bonne idée ; c'est pourquoi nous laissons généralement les sous-totaux de cette manière au front-end, de sorte que le package de rapports conservera les données ensemble. Si vous faites quelque chose comme convertir ceci en JSON, l'envoyer à un ordinateur distant et que la commande est perdue, l'information perd tout son sens. Personnellement, je ferais quelque chose de plus :

SELECT Gender, COALESCE(Role, '(TOTAL)') as Role, COUNT(*)
FROM employee
GROUP BY Gender, Role WITH ROLLUP

Il conserve les données homme-manager et femme-manager sur la ligne afin que vous puissiez les distinguer, mais il convertit le NULL en (Total) pour mieux renseigner sur ce dont il s'agit

Il y a d'autres choses à discuter comme si les colonnes contiennent elles-mêmes des valeurs NULL, mais je vous dirigerai vers The Fine Manual pour cela :https://dev.mysql.com/doc/refman/5.7/en/group-by-modifiers.html