2010-05-05 39 views
9

这一直困扰着我 - 为什么SQL语句中的GROUP BY子句要求包含所有非聚合列?这些列应该默认包含 - 一种“GROUP BY *” - 因为我甚至无法运行查询,除非它们全部包含在内。每一列都必须是聚合或在“GROUP BY”中指定,但似乎任何未汇总的内容都应该自动分组。为什么我需要显式指定SQL“GROUP BY”子句中的所有列 - 为什么不是“GROUP BY *”?

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

+0

相关http://stackoverflow.com/questions/416625/why-does-sql-force-me-to-repeat-all-non-aggregated-fields-from-my-select-clause-i – 2010-05-05 23:04:14

+0

啊 - 它是重复的。我会解决这个问题。 – SqlRyan 2010-05-05 23:14:11

+1

其多元化:http://stackoverflow.com/questions/2311034/is-sql-group-by-a-design-flaw – cindi 2010-05-06 07:47:22

回答

19

很难确切知道SQL语言的设计者在编写标准时想到什么,但这里是我的意见

SQL,作为一般规则,需要你明确说明你的期望和你的意图。该语言不会尝试“猜你的意思”,并自动填入空格。 这是一件好事

当你写一个查询时,最重要的考虑因素是它产生正确的结果如果您犯了一个错误,那么SQL解析器可能会告诉您更好,而不是猜测您的意图并返回可能不正确的结果。 SQL的声明性质(您声明您想要检索的内容而不是检索步骤)已经很容易导致无意中犯错误。 将fuzziniess引入语言语法不会使这个更好

事实上,我所能想到的每种情况下语言允许在快捷方式都引起了问题。举例来说,自然连接 - 您可以忽略要加入的列的名称,并允许数据库根据列名来推断它们。一旦列名更改(如他们自然做的一段时间内)- 与他们现有查询变化的语义。 这是坏的......很不好 - 你真的不希望这种魔术发生在你的数据库代码在幕后。这种设计选择

一个后果,但是,是SQL是一个冗长的语言中,你必须明确地表达你的意图。这可能导致必须编写比您想要的更多的代码,并且抱怨为什么某些构造如此冗长......但是在一天结束时 - 它就是这样。

0

就像这样简单:你需要对from子句中的每一列求sql结果,这意味着from子句SQL中的每一列,sql引擎会在内部对结果集进行分组,您。所以这就解释了为什么它会要求你提及所有列中的列,因为它不可能将它部分分组。如果您提到了group by子句,那么只有通过将所有列分组才能达到您的意图。这是一个数学限制。

0

唯一合乎逻辑的理由,我能想到的,以保持GROUP BY条款,因为它是可以包括未包含在您的分组选择列字段。

例如。

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

尽管在查询中其他位置没有显示第3列,但您仍然可以按结果对其值进行分组。 (当然,一旦你这样做了,你不能从结果中看出为什么这些记录是按原样分组的。)

它看起来像是一个简单的捷径,用于绝大多数常见的场景汇总列)将是一个简单而有效的工具,用于加速编码。

也许"GROUP BY *"

因为它已经是很常见的在SQL工具,允许结果列数列引用(即GROUP BY 1,2,3,等),这似乎是简单的还是要能够自动允许用户在一个按键中包含所有非聚合字段。