为什么我需要显式指定SQL中的所有列;分组方式;条款-为何不;分组依据*“;?

为什么我需要显式指定SQL中的所有列;分组方式;条款-为何不;分组依据*“;?,sql,group-by,aggregate,ansi-sql,sql-standards,Sql,Group By,Aggregate,Ansi Sql,Sql Standards,这一直困扰着我——为什么SQL语句中的GROUPBY子句要求我包含所有非聚合列?默认情况下,这些列应该包括在内,这是一种“GROUPBY*”,因为我甚至无法运行查询,除非它们都包括在内。每一列都必须是聚合或在“分组依据”中指定,但似乎任何未聚合的内容都应该自动分组 也许这是ANSI-SQL标准的一部分,但即便如此,我也不明白为什么。有人能帮我理解这种约定的必要性吗?很难确切地知道SQL语言的设计者在编写标准时是怎么想的,但以下是我的观点 一般来说,SQL要求您明确地陈述您的期望和意图。这种语言不

这一直困扰着我——为什么SQL语句中的GROUPBY子句要求我包含所有非聚合列?默认情况下,这些列应该包括在内,这是一种“GROUPBY*”,因为我甚至无法运行查询,除非它们都包括在内。每一列都必须是聚合或在“分组依据”中指定,但似乎任何未聚合的内容都应该自动分组


也许这是ANSI-SQL标准的一部分,但即便如此,我也不明白为什么。有人能帮我理解这种约定的必要性吗?

很难确切地知道SQL语言的设计者在编写标准时是怎么想的,但以下是我的观点

一般来说,SQL要求您明确地陈述您的期望和意图。这种语言不会试图“猜测你的意思”,而是自动地填空这是件好事

编写查询时,最重要的考虑因素是它会产生正确的结果。如果您犯了错误,最好由SQL解析器通知您,而不是猜测您的意图并返回可能不正确的结果。SQL的声明性本质(即声明要检索的内容,而不是如何检索的步骤)已经很容易在无意中出错在语言语法中引入模糊性并不能使其更好

事实上,我所能想到的每一种语言在哪里允许快捷方式都造成了问题。以自然联接为例,您可以省略要联接的列的名称,并允许数据库根据列名推断它们。一旦列名改变(随着时间的推移,它们自然会改变),现有查询的语义也随之改变这很糟糕。。。非常糟糕-您真的不希望在数据库代码的幕后发生这种神奇的事情


然而,这种设计选择的一个结果是,SQL是一种冗长的语言,您必须用它明确地表达您的意图。这可能导致您不得不编写比您可能喜欢的更多的代码,并抱怨为什么某些构造如此冗长。。。但归根结底,结果就是这样。

很简单,就是这样:您要求sql按from子句中的每一列对结果进行分组,这意味着对于from子句sql中的每一列,sql引擎都会先对结果集进行内部分组,然后再将其呈现给您。因此,这就解释了为什么它要求您也提及from中的所有列,因为它不可能将其部分分组。如果您提到GROUPBY子句,那么sql也只能通过对所有列进行分组来实现您的目的。这是一个数学限制。

我能想到的保留
GROUP BY
子句的唯一逻辑原因是,您可以在分组中包含未包含在选择列中的字段

比如说

Select column1, SUM(column2) AS sum
 FROM table1
 GROUP BY column1, column3
即使column3在查询的其他地方没有表示,您仍然可以根据它的值对结果进行分组。(当然,一旦这样做了,您就无法从结果中分辨出记录按原样分组的原因。)

对于绝大多数最常见的场景(按每个非聚合列分组)来说,这似乎是一个简单的快捷方式,它将是一个简单但有效的加速编码的工具

也许
“分组依据*”


由于在SQL工具中,允许按结果列编号(即
GROUP by 1,2,3,
等)引用列已经非常常见,因此允许用户在一次击键中自动包含所有非聚合字段似乎更简单。

相关Ah-这是一个重复。我将结束这个问题。这是一个多国家: