前几天我学了一些关于SQL的简单知识:
SELECT c FROM myTbl GROUP BY C
结果与:
SELECT DISTINCT C FROM myTbl
我好奇的是,SQL引擎处理命令的方式有什么不同,还是它们真的是一样的东西?
我个人更喜欢独特的语法,但我相信这更多是出于习惯而不是其他原因。
编辑:这不是一个关于聚合的问题。理解了GROUP BY与聚合函数的使用。
前几天我学了一些关于SQL的简单知识:
SELECT c FROM myTbl GROUP BY C
结果与:
SELECT DISTINCT C FROM myTbl
我好奇的是,SQL引擎处理命令的方式有什么不同,还是它们真的是一样的东西?
我个人更喜欢独特的语法,但我相信这更多是出于习惯而不是其他原因。
编辑:这不是一个关于聚合的问题。理解了GROUP BY与聚合函数的使用。
当前回答
GROUP BY有一个非常具体的含义,它与distinct函数不同。
GROUP BY使用选择的表达式对查询结果进行分组,然后可以应用聚合函数,这些函数将作用于每个组,而不是整个结果集。
这里有一个例子可能会有所帮助:
给定一个这样的表:
name
------
barry
dave
bill
dave
dave
barry
john
这个查询:
SELECT name, count(*) AS count FROM table GROUP BY name;
将产生如下输出:
name count
-------------
barry 2
dave 3
bill 1
john 1
这显然与使用DISTINCT非常不同。如果您想对结果进行分组,请使用group BY,如果您只想要特定列的唯一列表,请使用DISTINCT。这将使数据库有机会根据您的需要优化查询。
其他回答
MusiGenesis的回答在功能上是正确的,关于你的问题;SQL Server足够聪明,可以意识到如果你使用“Group By”而不使用任何聚合函数,那么你实际上的意思是“Distinct”——因此它会生成一个执行计划,就像你只是使用“Distinct”一样。
然而,我认为重要的是要注意Hank的回应-漫不经心的对待“Group By”和“Distinct”可能会导致一些有害的陷阱,如果你不小心的话。说这“不是一个关于聚合的问题”并不完全正确,因为您问的是两个SQL查询关键字之间的功能差异,其中一个是用于聚合的,而另一个不是。
锤子有时可以用来拧螺丝,但如果你手边有螺丝刀,那又何苦呢?
(为了便于类比,Hammer:螺丝刀::GroupBy: Distinct和screw =>获取表列中唯一值的列表)
对于你发布的查询,它们是相同的。但对于其他查询,这可能不是真的。
例如,它不等同于:
SELECT C FROM myTbl GROUP BY C, D
如果对多个列使用DISTINCT,结果集将不会像使用GROUP BY那样进行分组,并且不能对DISTINCT使用聚合函数。
从“SQL语言”的角度来看,这两种结构是等价的,你选择哪一种是我们都必须做出的“生活方式”选择之一。我认为DISTINCT更明确(因此对继承你代码的人更体贴)是一个很好的例子,但这并不意味着GROUP BY结构是一个无效的选择。
我认为“GROUP BY是用于聚合的”是错误的重点。人们应该意识到set函数(MAX, MIN, COUNT等)可以省略,这样他们就可以理解编码器的意图。
理想的优化器将识别等效的SQL结构,并始终相应地选择理想的计划。对于现实生活中选择的SQL引擎,您必须测试:)
PS注意DISTINCT关键字在select子句中的位置可能会产生不同的结果,例如对比:
SELECT COUNT(DISTINCT C) FROM myTbl;
SELECT DISTINCT COUNT(C) FROM myTbl;
我阅读了上面所有的评论,但除了聚合位之外,没有看到任何人指出Group By和Distinct之间的主要区别。
Distinct返回所有行,然后重复删除它们,而Group By则在算法逐条读取时重复删除行。
这意味着它们可以产生不同的结果!
例如,下面的代码会产生不同的结果:
SELECT distinct ROW_NUMBER() OVER (ORDER BY Name), Name FROM NamesTable
SELECT ROW_NUMBER() OVER (ORDER BY Name), Name FROM NamesTable
GROUP BY Name
如果表中有10个名字,其中一个是另一个的副本,那么第一个查询返回10行,而第二个查询返回9行。
原因就是我上面说的,这样他们就能表现得不一样!