在MySQL中没有子查询字段的模式计算?

Tim*_*Tim 4 mysql sql mode subquery

在我的应用程序中,每个产品组都有许多产品,每个产品都有一个制造商.这些关系通过存储在MySQL的InnoDB表product_groups与id领域,products与id,product_group和manufacturer领域.

有没有办法在每个产品组中找到最常见的制造商,而无需选择子查询?

这就是我目前正在做的事情:

SELECT product_groups.id,
  (
    SELECT manufacturer FROM products
    WHERE product_group = product_groups.id
    GROUP BY manufacturer
    ORDER BY count(*) DESC
    LIMIT 1
  ) manufacturer_mode
FROM product_groups;
Run Code Online (Sandbox Code Playgroud)

Zan*_*ien 5

尝试此解决方案:

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
Run Code Online (Sandbox Code Playgroud)

说明:

这仍然使用一种子查询形式,但只执行一次,而不是逐行执行,例如在原始示例中.

它的工作原理是首先选择product_groupid,制造商以及制造商为每个特定组出现的次数.

执行后FROM子选择看起来像这样(只是在这里编写数据):

product_group   |   manufacturer   |    occurrences
---------------------------------------------------
1               |   XYZ            |    4
1               |   Test           |    2
1               |   Singleton      |    1
2               |   Eloran         |    2
2               |   XYZ            |    1
Run Code Online (Sandbox Code Playgroud)

现在我们有了子选择结果,我们需要在occurences每个产品组的字段中挑选出具有最大值的行.

在外部查询中,我们再次按product_group字段对子选择进行分组,但这次只对product_group字段进行分组.现在,当我们在GROUP BY这里工作时,我们可以在MySQL中使用一个非常引人注目的函数GROUP_CONCAT,我们可以使用它来将制造商连接在一起并按我们想要的任何顺序连接.

...GROUP_CONCAT(a.manufacturer ORDER BY a.occurrences DESC SEPARATOR ':::'...
Run Code Online (Sandbox Code Playgroud)

我们在这里做的是将每个product_groupID 组合在一起的制造商连接在一起,ORDER BY a.occurrences DESC确保具有最多外观的制造商首先出现在连接列表中.最后,我们将每个制造商分开:::.这个结果product_group 1将如下所示:

XYZ:::Test:::Singleton
Run Code Online (Sandbox Code Playgroud)

XYZ首先出现,因为它在该occurance领域具有最高价值.我们只需要选择XYZ,所以我们包住内的串联SUBSTRING_INDEX,这将允许我们只挑选基于该列表的第一个元素:::分隔符.

最终结果将是:

product_group    |    manufacturer_mode
---------------------------------------
1                |    XYZ
2                |    Eloran
Run Code Online (Sandbox Code Playgroud)