在 postgreSQL 文档中,它说:
当 GROUP BY 存在时,SELECT 列表表达式引用未分组的列是无效的,除非在聚合函数中或者如果未分组的列在功能上依赖于分组的列,否则将返回多个可能的值未分组的列
我不明白关于“ there would otherwise be more than one possible value to return for an ungrouped column
”的部分。
有人可以给我一个例子吗?如何为取消分组列返回一个以上的可能值?
在 postgreSQL 文档中,它说:
当 GROUP BY 存在时,SELECT 列表表达式引用未分组的列是无效的,除非在聚合函数中或者如果未分组的列在功能上依赖于分组的列,否则将返回多个可能的值未分组的列
我不明白关于“ there would otherwise be more than one possible value to return for an ungrouped column
”的部分。
有人可以给我一个例子吗?如何为取消分组列返回一个以上的可能值?
考虑这张表:
col_1 | col_2 | col_3
A 10 10
A 11 20
B 20 40
C 40 60
并尝试运行对 col_3 的值求和的查询
SELECT col_1, col_2, SUM(col_3)
FROM t1
GROUP BY col_1
上面的查询可以有 2 个可能的输出:
Output 1: Here, col_2 = 10
---------------------------
col_1 | col_2 | SUM(col_3)
A 10 30
B 20 40
C 40 60
Output 2: Here, col_2 = 11
---------------------------
col_1 | col_2 | SUM(col_3)
A 11 30
B 20 40
C 40 60
这是因为 col_2 没有包含在 GROUP BY 子句中。col_3 的求和基于 col_1 的分组按预期发生,但现在 SQL 引擎不知道您是否希望 A 的行 col_2 为 11 或 11。因此,“否则将返回多个可能的值对于未分组的列"
上述查询适用于 MySQL,它将随机返回上述 2 个输出之一,而 Oracle/SQL Server 将抛出您提到的错误
否则,未分组的列将返回多个可能的值
让我尝试用一小部分数据来解释这一点:
CREATE TABLE yourtable ([year] int, [amt] int);
INSERT INTO yourtable ([year], [amt])
VALUES
(2012, 50),
(2012, 60),
(2011, 100),
(2011, 89),
(2013, 25);
这个样本有 3 个不同的年份,现在我们想要获得每年的金额总和。
如果您使用查询:
select year, sum(amt) TotalPerYear
from yourtable
并且您没有GROUP BY
提供该Year
列,那么数据库引擎将如何知道要为该年份选择什么值,因为该列中有多个值。
这GROUP BY
是说我想要每年的总和,并不是说我想要它决定的任何一年的总和。
select year, sum(amt) TotalPerYear
from yourtable
group by year
选择中的GROUP BY
每一列,确保您获得分组列的正确聚合。
MySQL 是一个允许这种行为的数据库,它在文档中明确指出,在选择列表中包含不在 group by 或聚合函数中的列可能会导致意外结果。
来自 MySQL 文档:
您可以使用此功能通过避免不必要的列排序和分组来获得更好的性能。但是,这主要在每个未在 GROUP BY 中命名的非聚合列中的所有值对于每个组都相同时很有用。服务器可以自由地从每个组中选择任何值,因此除非它们相同,否则选择的值是不确定的。此外,从每个组中选择值不会受到添加 ORDER BY 子句的影响。在选择了值之后对结果集进行排序,并且 ORDER BY 不会影响服务器选择的值。
假设您有一张人桌……姓名、城市、电话号码。你想按城市统计人数。因此,您选择 * 的城市和计数并按城市分组。在查询中包含电话号码(未分组)是没有意义的,因为每个分组很可能有多个电话号码,并且数据库不知道您想要什么。