2016-02-12 43 views
1

我对SQL中使用汇总函数的理解是,select语句中不使用汇总函数的每个字段都应在group by语句中列出。SQL语法 - 为什么我们需要在SQL group-by语句中列出单个字段?

select a, b, c, sum(n) as sum_of_n 
from table 
group by a, b, c 

我的问题是,为什么我们需要列出字段?如果不是SQL语法分析程序的方式来实现,我们可以告诉它group,它可以基于哪个字段是select找出群体和不使用汇总函数?:

select a, b, c, sum(n) as sum_of_n 
from table 
group 

我感觉自己在编写SQL代码时不必要地重复自己。在什么情况下,我们不希望它自动解决这个问题,或者它不能自动解决这个问题?

+0

当你的rdbms是MySQL时,就会出现这种情况。 –

+2

@DanBracuk,除了MySQL以外,可以让你省略“GROUP BY”......通常是为了自己的利益。 – JNevill

回答

2

为了减少您的声明中的错误的机会。明确指出GROUP BY列有助于确保用户编写的内容有意编写。您可能会惊讶于在Stackoverflow上显示的帖子数量,其中用户在无意义的列上进行分组,但他们不知道为什么他们没有获得他们期望的数据。

此外,请考虑用户可能想要在实际上处于SELECT语句中的列数多的情况下进行分组。例如,如果我想的最多的钱平均,我的客户已经花了那么我可能会写这样的事:

SELECT 
    AVG(max_amt) 
FROM (SELECT MAX(amt) FROM Invoices GROUP BY customer_id) SQ 

在这种情况下,我不能简单地用GROUP,我需要拼写出列(s)我正在分组。 SQL引擎可以允许用户明确列出列,但如果他们没有列出,则使用默认值,但是错误的几率急剧增加。

想到它的一种方式就像强类型编程语言。让程序员明确地说明事情会减少出现错误的可能性,因为引擎假设程序员没有想到。

+0

哦,我并不感到惊讶的是,显示出来的形式不佳的查询数量 - 我亲眼见过他们。 –

+0

我个人不记得上次需要写这样的查询,但我想这会偶尔有用。我认为,如果您不希望所有非汇总功能字段分组在一起,设计更好的查询语言将允许您选择指定要分组的字段。也许甚至可以使用'group by *'语法,其中'*'仅指非汇总函数字段。我认为只有这么多的人手才能做,而且让人们两次陈述他们的意图并不一定会简化程序,也不会让“简单”得到预期的结果。 –

0

这是明确确定如何分组记录所需的,因为例如,您可以使用未列于结果集中的列进行分组。

但是,有RDBMS允许不使用像MySQL这样的集合函数来指定GROUP BY子句。

0

我的第一反应会是“这是个什么” =) 但在经过思考它,TSQL的工作原理是这样做的原因是因为SELECTGROUP BY是所有操作的事情两个不同的部分查询。 这可能不是最好的例子,但它确实表明您可以在不同的(以及'更多')字段上输入GROUP,而不是您实际上的SELECT

SELECT brand = Convert(varchar(100), ''), model = Convert(varchar(100), ''), some_number = Convert(int, 0) 
    INTO #test 
WHERE 1 = 2 

INSERT #test (brand, model, some_number) 
VALUES ('Ford', 'Focus', 10), 
     ('Ford', 'Focus', 25), 
     ('Ford', 'Kagu', 23), 
     ('DMC', '12', 88) 


SELECT brand, model, MAX(some_number) 
    FROM #test 
    GROUP BY brand, model 

SELECT brand, MAX(some_number) 
    FROM #test 
    GROUP BY brand, model 

并非所有的RDBMS都是这样的,例如, MySQL允许从GROUP BY中删除仍在SELECT部分中的字段。从我所看到的,然后选择一个随机值('没有这样的事情,作为一个隐含的第一'),并在SELECT中使用..我认为,我对MySQL的知识是相当有限,但我见过一些例子在这里和那里,他们总是困惑我,因为我习惯了刚刚描述的TSQL的严格要求。

+0

它似乎最大打我吧=) – deroby

0

此外,您可以通过将列在不同的顺序组比选择

select a, b, c, sum(d) 
from table 
group by c,a,b 

也有很多DB的,你可以跳过列名,你可以指定哪些列将要列入该组通过使用选择的位置

select a, b, c, sum(d) 
from table 
group by 3,1,2 
+2

我不确定字段序数会在“GROUP BY”中产生差异。 – JNevill

+0

至少在不键入列名时至少节省时间和拼写错误 – mdem

+0

我的意思是切换“GROUP BY”中字段的顺序。尽管完全同意序数参考!如果我不能“GROUP BY 1,2,3,4,5,6,7,8,9,10,11,12,13,14”并最终发布OP等问题,我会坚持下去。 – JNevill