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

Calcul de mode sans champ de sous-requête dans MySQL ?

Essayez cette solution :

SELECT
    a.product_group,
    SUBSTRING_INDEX(GROUP_CONCAT(a.manufacturer ORDER BY a.occurrences DESC SEPARATOR ':::'), ':::', 1) AS manufacturer_mode
FROM
    (
        SELECT
            aa.product_group,
            aa.manufacturer,
            COUNT(*) AS occurrences
        FROM
            products aa
        GROUP BY
            aa.product_group,
            aa.manufacturer
    ) a
GROUP BY
    a.product_group

Explication :

Cela utilise toujours une forme de sous-requête, mais qui ne s'exécute qu'une seule fois par opposition à une qui s'exécute ligne par ligne comme dans votre exemple d'origine.

Cela fonctionne en sélectionnant d'abord le product_group id, le fabricant et le nombre de fois que le fabricant apparaît pour chaque groupe particulier.

Le FROM la sous-sélection ressemblera à ceci après l'exécution (juste en créant des données ici) :

product_group   |   manufacturer   |    occurrences
---------------------------------------------------
1               |   XYZ            |    4
1               |   Test           |    2
1               |   Singleton      |    1
2               |   Eloran         |    2
2               |   XYZ            |    1

Maintenant que nous avons le résultat de la sous-sélection, nous devons sélectionner la ligne qui a le maximum dans les occurences champ pour chaque groupe de produits.

Dans la requête externe, nous regroupons à nouveau la sous-sélection par le product_group champ, mais cette fois, seulement le product_group champ. Maintenant, quand nous faisons notre GROUP BY ici, nous pouvons utiliser une fonction vraiment convaincante dans MySQL appelée GROUP_CONCAT que nous pouvons utiliser pour concaténer les fabricants ensemble et dans l'ordre de notre choix.

...GROUP_CONCAT(a.manufacturer ORDER BY a.occurrences DESC SEPARATOR ':::'...

Ce que nous faisons ici, c'est concaténer les fabricants qui sont regroupés par product_group id, le ORDER BY a.occurrences DESC s'assure que le fabricant avec le plus d'apparitions apparaît en premier dans la liste concaténée. Enfin, nous séparons chaque fabricant avec ::: . Le résultat de ceci pour product_group 1 ressemblera à :

XYZ:::Test:::Singleton

XYZ apparaît en premier car il a la valeur la plus élevée dans l'occurance champ. Nous seulement voulez sélectionner XYZ , donc nous enfermons la concaténation dans SUBSTRING_INDEX , ce qui nous permettra de sélectionner uniquement le premier élément de la liste en fonction du ::: délimiteur.

Le résultat final sera :

product_group    |    manufacturer_mode
---------------------------------------
1                |    XYZ
2                |    Eloran