【问题标题】:MySQL - edge case use of GROUP BYMySQL - GROUP BY 的边缘案例使用
【发布时间】:2013-04-12 08:28:21
【问题描述】:

我对 GROUP BY 的理解是它的标准用途是聚合项目。所以一个典型的例子可能是:

select 

count(id),
department,

from table
group by department

以上将计算每个部门的所有 id。

所以,我学会了一个使用 group by 的非常有用(但可能非常狡猾!)的技巧。我想知道这种用法是否有任何问题。尽管查询按预期运行[在所有情况下都按预期结果],但我的蜘蛛侠感觉有点刺痛......

想象以下数据集:

id  |  user_id  |  cost  |  note
----------------------------------
1         1         120     Test 1
2         1         150     Test 2
3         2         100     Test 3
4         3         120     Test 4

现在如果我们执行以下 SQL:

select * from table
group by user_id

你得到以下结果集。

id  |  user_id  |  cost  |  note
----------------------------------
1         1         120     Test 1
3         2         100     Test 3
4         3         120     Test 4

查询显然如下运行:

  • 遍历表
  • 当找到可分组的用户 ID 时,忽略后面的用户 ID
  • 返回此唯一 user_id 项目表

实际上我得到了一个具有特定边界的“唯一”,并且我可以从这个列表中选择 *。 此外,通过在 order by 之前对表进行排序,我可以使用它来过滤所有成本。

所以 - 这也是你所期望的......但是:

在上面的示例中 - 假设我实际上确保对于 user_id 1,显示值 120(而不是其他可能的值 - 在本例中为 150)。然后 120 似乎可以保证是响应。 然后,该方法可以按字母/数字/其他高级过滤器等顺序进行排序...然后使用这种排序来强制表中的第一项成为“答案”。

我想要做的实际查询非常复杂。使用 MIN 或类似的方法不适合我想要的最终值......但是:这种“订购表格然​​后使用 group by 获取第一个唯一项目”的方法实际上非常优雅(我认为)。 我实际上是在 4 个字段中使用 group by,这与其他 SQL 结合使用得到了正确的答案。

所以。在那长长的背景之后:一个问题!

我使用的所有文档都只讨论了将 group by 与聚合函数一起使用。我似乎找不到 JUST group by 的行为。 这让我觉得是两件事之一:

  • 未记录的正确(错误)用例
  • 我正在使用的任何版本的 mySQL 的意外行为。

那么...是哪一个? 如果这是一个正确但边缘情况的行为,那就太好了。如果我在欺骗 SQL 引擎吐出一些东西,那么我没有证据证明这与未来的版本兼容,所以我很难使用它。

大家提前干杯。

【问题讨论】:

标签: mysql group-by


【解决方案1】:

在其他RDMS 中,您不能对不在GROUP BY 子句中的字段使用没有聚合函数的GROUP BY 子句,这是有道理的,因为这些字段需要聚合(最小值、最大值、计数等)但在mysql 它允许您使用没有任何聚合函数的字段,它会显示该字段遇到的第一个值。
mysql 的这种行为有利有弊:
- 优点:您可以使用它来获取该字段遇到的第一个值
- 缺点:如果您不知道这种行为,您可能会得到损坏的结果

【讨论】:

    【解决方案2】:

    在通过上述链接/帮助进行调查后,我认为不幸的是:虽然答案是正确的,但不能保证它是正确的......更准确地说,它是“不确定的”。

    在我多次成功使用此功能后,我非常有信心内部运作是“先到先得”,但正如规范中所说,这不能保证,所以我不能依赖它。

    为大家欢呼。已对所有 cmets 投了赞成票。

    【讨论】:

      猜你喜欢
      • 2010-10-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-03-30
      • 2012-03-31
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多