Zkuste toto řešení:
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
Vysvětlení:
Toto stále používá formu poddotazu, ale takový, který se provede pouze jednou, na rozdíl od toho, který se spouští na základě řádku po řádku, jako ve vašem původním příkladu.
Funguje to tak, že nejprve vyberete product_group
id, výrobce a počet, kolikrát se výrobce objeví pro každou konkrétní skupinu.
FROM
sub-select bude po spuštění vypadat nějak takto (zde jen tvoří data):
product_group | manufacturer | occurrences
---------------------------------------------------
1 | XYZ | 4
1 | Test | 2
1 | Singleton | 1
2 | Eloran | 2
2 | XYZ | 1
Nyní, když máme výsledek dílčího výběru, musíme vybrat řádek, který má maximum v occurences
pole pro každou skupinu produktů.
Ve vnějším dotazu seskupujeme podvýběr znovu podle product_group
pole, ale tentokrát pouze product_group
pole. Nyní, když uděláme naše GROUP BY
zde můžeme použít opravdu působivou funkci v MySQL nazvanou GROUP_CONCAT
které můžeme použít ke spojení výrobců dohromady a v libovolném pořadí.
...GROUP_CONCAT(a.manufacturer ORDER BY a.occurrences DESC SEPARATOR ':::'...
To, co zde děláme, je zřetězení výrobců, kteří jsou seskupeni podle product_group
id, ORDER BY a.occurrences DESC
zajišťuje, aby se výrobce s nejvíce výskyty objevil jako první ve zřetězeném seznamu. Nakonec oddělíme každého výrobce pomocí :::
. Výsledek pro product_group
1
bude vypadat takto:
XYZ:::Test:::Singleton
XYZ
se objeví jako první, protože má nejvyšší hodnotu v occurance
pole. My pouze chcete vybrat XYZ
, takže zřetězení zapouzdříme do SUBSTRING_INDEX
, což nám umožní vybrat pouze první prvek seznamu na základě :::
oddělovač.
Konečný výsledek bude:
product_group | manufacturer_mode
---------------------------------------
1 | XYZ
2 | Eloran