【问题标题】:When is GROUP BY required for aggregate functions?聚合函数何时需要 GROUP BY?
【发布时间】:2016-10-28 16:01:18
【问题描述】:

我有一个名为myEntity 的表,如下所示:

- id (PK INT NOT NULL)
- account_id (FK INT NOT NULL)
- key (INT NOT NULL.  UNIQUE for given account_id)
- name (VARCHAR NOT NULL.  UNIQUE FOR given account_id)

我不希望将主键id 暴露给用户,并为此添加了keykey 类型充当给定 accounts_id 的自动增量列,这需要由应用程序手动完成。我最初计划制作主键组合id-account_id,但是,该表已连接到其他表,并且在我知道之前,我的表中有四列可能是一个。虽然account_id-nameaccount_id-key 的作用相同,但key 更小,并且在客户端请求多条记录时将网络流量降至最低。是的,我知道它没有正确规范化,虽然不是我的直接问题,但如果有任何建设性的批评,我将不胜感激。

抱歉,杂乱无章...聚合函数何时需要 GROUP BY?例如,下面的呢? https://stackoverflow.com/a/1547128/1032531 没有显示。需要吗?

SELECT COALESCE(MAX(key),0)+1 FROM myEntity WHERE accounts_id=123;

【问题讨论】:

    标签: mysql group-by aggregate-functions


    【解决方案1】:

    您以查询为例,不需要GROUP BY。为了便于说明,我将其简化如下。

    SELECT MAX(key)
      FROM myEntity
     WHERE accounts_id = 123
    

    为什么该查询不需要GROUP BY?因为您只希望结果集中有一行描述特定帐户。

    如果您想要一个结果集来描述您的所有帐户,每个帐户只有一行,该怎么办?然后你会使用这个:

     SELECT accounts_id, MAX(key)
       FROM myEntity
      GROUP BY accounts_id
    

    看看情况如何?对于accounts_id 的每个不同值,您会在此结果集中获得一行。顺便说一句,MySQL 的查询计划器知道

     SELECT accounts_id, MAX(key)
       FROM myEntity
      WHERE accounts_id = '123'
      GROUP BY accounts_id
    

    相当于省略GROUP BY子句的相同查询。

    还有一点要知道:如果您的表中有一个复合索引 (accounts_id, key),那么所有这些查询将几乎奇迹般地快,因为查询计划器将通过非常有效的 loose index scan. 满足它们,这是特定于 @987654331 @ 和 MIN() 聚合函数。松散索引扫描不能用于SUM()AVG() 或类似功能;那些需要严格的索引扫描。

    【讨论】:

    • 谢谢奥利。很好的解释。我将添加复合索引。题外话,但你经常使用复合键吗?知道我对它们导致额外列的扩散是什么意思吗?也许没什么大不了的..
    • 复合索引用于特定目的。阅读use-the-index-luke.com 进行讨论。
    【解决方案2】:

    只有在需要时才需要它。例如,如果你想返回所有的键,你可以使用

    SELECT COALESCE(MAX(key),0)+1 FROM myEntity GROUP BY accounts_id

    而不是您的选择。但是您的选择很好(尽管您的结构似乎让自己有些困难,但我不知道您要解决什么问题)

    【讨论】:

      猜你喜欢
      • 2018-11-07
      • 2014-08-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多