SELECT列表中的所有列都必须出现在GROUP BY子句中

use*_*142 46 sql

我的讲师说:

SELECT列表中的所有列名必须出现在GROUP BY子句中,除非name仅用于聚合函数

我只是想要对此进行一些确认,因为我无法想出为什么它应该是真实的合理解释......

Rob*_* P. 34

想象一下:

    A    B    C
   Cat   10   False
   Dog   25   True
   Dog   20   False
   Cat   5    False
Run Code Online (Sandbox Code Playgroud)

如果您选择A,B和仅按A组 - 您的输出是什么?你只有两行(或元组),因为你有两个A值 - 但它如何显示B?

如果按A,B分组,你会得到四行,没有问题.如果按A分组并在B上执行函数(如SUM(B)),则会再次获得两行:

    Cat    15
    Dog    45
Run Code Online (Sandbox Code Playgroud)

但是如果你选择A,B并且只选择A组 - 它不知道该怎么做.说实话,我相信有一些数据库会在这种情况下为B选择一个随机值,我相信有一些会给你一个错误信息.


Mik*_*ll' 16

这在历史上是正确的.省略未聚合的列会导致不确定的行为.SQL旨在完全确定行为.

但SQL标准最近已更改,让你从GROUP BY忽略那些功能依赖于该列子句中的列在GROUP BY.PostgreSQL遵循最新的SQL标准.(这不是唯一的.)行为仍然是完全确定的.

create table a (
  a_id integer primary key,
  xfr_date date not null
);

create table b (
  a_id integer not null references a (a_id),
  recd_date date not null,
  units_recd integer not null 
    check (units_recd >= 0),
  primary key (a_id, recd_date)
);

select a.a_id, a.xfr_date, sum(b.units_recd)
from a
inner join b on a.a_id = b.a_id
group by a.a_id; -- The column a.xfr_date is functionally dependent 
                 -- on a.a_id; it doesn't have to appear in the 
                 -- GROUP BY clause.
Run Code Online (Sandbox Code Playgroud)

与SQL标准的显着偏差是MySQL.它允许您省略GROUP BY中的所有内容.但是,当您省略SELECT列表中的列时,该设计选择会使其行为不确定.


Kib*_*bee 7

实际上,在MySQL中,您不必按所有列进行分组.您可以按所需的列分组.问题是,它只会为不在组中的字段提取一个随机值(来自组中可用行的集合).如果你知道你正在通过一个唯一键的东西进行分组,那么对其他字段进行分组就没有意义了,因为无论如何它们都已经具有相同的值.它实际上可以加速,以便在完全没有必要时不必按每个字段进行分组.