试试这个解决方案:
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
解释:
这仍然使用子查询的一种形式,但它只执行一次,而不是像在原始示例中那样逐行执行。
它的工作原理是首先选择product_group
id、制造商以及制造商在每个特定组中出现的次数。
子选择在FROM
执行后看起来像这样(这里只是弥补数据):
product_group | manufacturer | occurrences
---------------------------------------------------
1 | XYZ | 4
1 | Test | 2
1 | Singleton | 1
2 | Eloran | 2
2 | XYZ | 1
现在我们有了子选择结果,我们需要occurences
为每个产品组选择字段中具有最大值的行。
在外部查询中,我们再次按字段对子选择进行分组,product_group
但这一次,只有product_group
字段。现在,当我们在GROUP BY
这里进行操作时,我们可以在 MySQL 中使用一个非常引人注目的函数GROUP_CONCAT
,我们可以使用它以我们想要的任何顺序将制造商连接在一起。
...GROUP_CONCAT(a.manufacturer ORDER BY a.occurrences DESC SEPARATOR ':::'...
我们在这里所做的是将每个product_group
id 组合在一起的制造商连接在一起,以ORDER BY a.occurrences DESC
确保出现最多的制造商出现在连接列表中的第一位。最后,我们将每个制造商与:::
. 这个 for 的结果product_group
1
将如下所示:
XYZ:::Test:::Singleton
XYZ
首先出现,因为它在该occurance
字段中具有最高值。我们只想选择XYZ
,因此我们将串联包含在 中SUBSTRING_INDEX
,这将允许我们仅根据:::
分隔符选择列表的第一个元素。
最终结果将是:
product_group | manufacturer_mode
---------------------------------------
1 | XYZ
2 | Eloran