这总是困扰着我 - 为什么SQL语句中的小组按子句要求我包括所有非聚合列?默认情况下应包含这些列 - 一种“组为 *” - 因为除非所有查询都包括在内,否则我什至无法运行查询。每个列必须是汇总或在“组”中指定的,但是似乎应该自动分组任何未聚集的东西。

也许这是ANSI-SQL标准的一部分,但即使如此,我也不明白为什么。有人可以帮助我了解此公约的需求吗?

有帮助吗?

解决方案

很难确切知道SQL语言的设计师在编写标准时在想什么, 但这是我的看法.

通常,SQL要求您明确陈述您的期望和意图。该语言不尝试 “猜猜你的意思”, 并自动填充空白。 这是一件好事.

当您编写查询时,最重要的考虑因素是 产生正确的结果. 如果您犯了一个错误,那么SQL解析器向您通知您可能会更好,而不是猜测您的意图和返回结果可能是不正确的。 SQL的声明性质(在其中说明要检索的内容而不是如何检索步骤)已经使无意中犯错误变得容易。 将fuzziniess引入语言语法不会使它变得更好.

实际上,我可以想到语言允许的何处 快捷方式 引起了问题。以自然连接为例 - 您可以在其中省略要加入的列的名称,并允许数据库根据列名推断它们。一旦列的名称更改(随着时间的流逝,它们自然而然地做) - 现有查询的语义随之改变. 这是不好的...非常糟糕 - 您真的不想要这种 魔法 发生在数据库代码中的幕后。

但是,这种设计选择的结果之一是SQL是一种详细的语言,您必须在其中明确表达意图。 这可能会导致编写比您想要的更多的代码,并抓住为什么某些构造如此冗长的原因……但是归根结底 - 它就是它的本质。

其他提示

这很简单:您要求SQL按子句中的每个列对结果进行分组,这意味着从子句SQL中的每个列中,SQL Engine将内部对结果集进行分组,然后将结果集提交给您。因此,这解释了为什么它要求您提及来自中间的所有列,因为它不可能部分地组。如果您通过条款提到了该组,则只能通过对所有列进行分组才能实现您的意图。这是数学限制。

我能想到的唯一合乎逻辑的原因是 GROUP BY 条款是因为您可以在分组中包含未包含在选择列中的字段。

例如。

Select column1, SUM(column2) AS sum
 FROM table1
 GROUP BY column1, column3

即使列3在查询中的其他位置并未表示,您仍然可以根据其值对结果进行分组。 (当然,一旦完成了,就无法从结果看出为什么记录被按原样进行分组。)

对于绝大多数最常见的情况(由每个非聚集列进行分组)似乎是一个简单的快捷方式,这将是一个简单而有效的工具,用于加快加速编码。

也许 "GROUP BY *"

由于在SQL工具中已经很常见,可以通过结果列编号引用对列的引用(即。 GROUP BY 1,2,3, 等等。)似乎仍然可以使用户自动将所有非聚合字段自动在一个键中包含。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top