mysql - 是否有更清晰的方法来处理不在聚合函数或 GROUP BY 子句中的字段?
问题描述
我经常遇到这样的查询:
SELECT
a.Id,
a.A,
a.B,
a.C,
SUM(b.Foo) AS foo
FROM
TableA AS a
JOIN TableB AS b
ON a.Id = b.TableAId
GROUP BY a.Id;
在 SQL Server(如果为真,还有 MySQL ONLY_FULL_GROUP_BY
)中,这个查询不好。一切都必须是 a) 在聚合函数中,或 b) 在GROUP BY
.
我的问题是这两种解决方案看起来都很糟糕且具有误导性。如果你选择一个随机聚合函数,MAX()
你最终会得到:
SELECT
a.Id,
MAX(a.A) AS A,
MAX(a.B) AS B,
MAX(a.C) AS C,
SUM(b.Foo) AS foo
FROM
TableA AS a
JOIN TableB AS b
ON a.Id = b.TableAId
GROUP BY a.Id;
这个查询看起来像我们关心 、 和 的最大值a.A
,a.B
并且a.C
混淆了最大值没有意义的事实。
GROUP BY
好一点:
SELECT
a.Id,
a.A,
a.B,
a.C,
SUM(b.Foo) AS foo
FROM
TableA AS a
JOIN TableB AS b
ON a.Id = b.TableAId
GROUP BY a.Id, A, B, C;
但它仍然不是最佳的。在具有复杂分组的大查询中,拥有所有这些额外的字段会使阅读变得更加困难,我最初的印象是这里有一些实际上并不存在的额外分组层次结构。
我的背景主要是在 MySQL 中ONLY_FULL_GROUP_BY
关闭,所以我发现 SQL Server 中的这个限制是不必要的。我希望两者之间有一些快乐的媒介;TableA
计算机查看此查询并看到不需要聚合字段,而来自TableB
(besides TableAId
)的任何字段都需要聚合,这似乎是一件简单的事情。
有什么想法吗?
解决方案
这不是 SQL Server 问题!您看到的行为是 MySQL 损坏(通常),这就是为什么现在的默认设置是禁止该行为。也就是说,SQL 标准允许通过表中的唯一列进行聚合并选择表中的其他列。但是,我认为只有 Postgres 实现了这一点。
这是您遗漏的一种方法:
SELECT a.*, b.foo
FROM TableA a JOIN
(SELECT b.TableAId, SUM(b.Foo) as foo
FROM TableB b
GROUP BY b.TableAId
) b
ON a.Id = b.TableAId;
推荐阅读
- javascript - 直接发布到 Facebook 没有共享对话框问题
- arrays - “如何从 Ruby 数组中删除一个元素,该元素只是另一个元素的反转?”
- php - PHP 生成器:即使调用了 break,如何始终清理资源?
- mysql - COUNT(*) 附近的语法不正确
- python - 基于正则表达式拆分列的模式
- c++ - QT label setText() 同时保留文本格式
- html - django中的提交按钮刷新页面而不保存
- java - Sonarqube - 使用 Lombok @data 删除这个未使用的私有字段 Code Smell
- bash - SED 的替换字符串被认为是单行字符串,而它包含换行符
- angular - 使用 Reactive Form Angular 在表单数组中添加新行