试试这个解决方案:
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 确保出现最多的制造商出现首先 在串联列表中。最后,我们用::: 分隔每个制造商。 product_group 1 的结果如下:
XYZ:::Test:::Singleton
XYZ 首先出现,因为它在occurance 字段中具有最高值。我们仅想选择XYZ,因此我们将串联包含在SUBSTRING_INDEX 中,这将允许我们仅根据::: 分隔符选择列表的第一个元素。
最终结果将是:
product_group | manufacturer_mode
---------------------------------------
1 | XYZ
2 | Eloran