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