前几天我学了一些关于SQL的简单知识:

SELECT c FROM myTbl GROUP BY C

结果与:

SELECT DISTINCT C FROM myTbl

我好奇的是,SQL引擎处理命令的方式有什么不同,还是它们真的是一样的东西?

我个人更喜欢独特的语法,但我相信这更多是出于习惯而不是其他原因。

编辑:这不是一个关于聚合的问题。理解了GROUP BY与聚合函数的使用。


当前回答

有时它们可能会给你同样的结果,但它们是在不同的意义/情况下使用的。主要的区别在于语法。

请仔细注意下面的例子。DISTINCT用于过滤掉重复的值集。(6, cs, 9.1)和(1,cs, 5.5)是两个不同的集合。DISTINCT会显示这两行,而GROUP BY Branch只显示一组。

 SELECT * FROM student; 
+------+--------+------+
| Id   | Branch | CGPA |
+------+--------+------+
|    3 | civil  |  7.2 |
|    2 | mech   |  6.3 |
|    6 | cs     |  9.1 |
|    4 | eee    |  8.2 |
|    1 | cs     |  5.5 |
+------+--------+------+
5 rows in set (0.001 sec)

SELECT DISTINCT * FROM student; 
+------+--------+------+
| Id   | Branch | CGPA |
+------+--------+------+
|    3 | civil  |  7.2 |
|    2 | mech   |  6.3 |
|    6 | cs     |  9.1 |
|    4 | eee    |  8.2 |
|    1 | cs     |  5.5 |
+------+--------+------+
5 rows in set (0.001 sec)

SELECT * FROM student GROUP BY Branch;
+------+--------+------+
| Id   | Branch | CGPA |
+------+--------+------+
|    3 | civil  |  7.2 |
|    6 | cs     |  9.1 |
|    4 | eee    |  8.2 |
|    2 | mech   |  6.3 |
+------+--------+------+
4 rows in set (0.001 sec)

如果不使用一些额外的子句或条件,有时GROUP by子句可以实现的结果无法通过DISTINCT实现。如上述情况。

要得到与DISTINCT相同的结果,您必须在GROUP BY子句中传递所有列名,如下所示。看看句法上的区别。在这种情况下,您必须了解所有列名才能使用GROUP BY子句。

SELECT * FROM student GROUP BY Id, Branch, CGPA;
+------+--------+------+
| Id   | Branch | CGPA |
+------+--------+------+
|    1 | cs     |  5.5 |
|    2 | mech   |  6.3 |
|    3 | civil  |  7.2 |
|    4 | eee    |  8.2 |
|    6 | cs     |  9.1 |
+------+--------+------+

此外,我还注意到GROUP BY默认情况下以升序显示结果,而DISTINCT则不会。但我不太确定。这可能是不同的供应商。

来源:https://dbjpanda.me/dbms/languages/sql/sql-syntax-with-examples#group-by

其他回答

从“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

你之所以注意到这一点,是因为你只选择了一列。

尝试选择两个字段,看看会发生什么。

Group By的用法如下:

SELECT name, SUM(transaction) FROM myTbl GROUP BY name

这将显示每个人的所有交易的总和。

当你指的是DISTINCT时,请不要使用GROUP BY,即使它们的工作方式是一样的。我假设您正在尝试从查询中减少毫秒数,我必须指出,开发人员的时间比计算机的时间要昂贵几个数量级。

在Teradata透视图:

从结果集的角度来看,在Teradata中使用DISTINCT或GROUP BY并不重要。答案集是一样的。

从性能的角度来看,这是不一样的。

要了解什么会影响性能,您需要知道在使用DISTINCT或GROUP BY执行语句时Teradata上发生了什么。

在DISTINCT的情况下,行被立即重新分配,而不发生任何预聚合,而在GROUP BY的情况下,第一步完成预聚合,然后才在amp之间重新分配唯一值。

现在不要认为GROUP BY从性能角度来看总是更好。当您有许多不同的值时,GROUP BY的预聚合步骤不是很有效。Teradata必须对数据进行排序以删除重复项。在这种情况下,最好先重新分配,即使用DISTINCT语句。只有当有许多重复值时,GROUP BY语句可能是更好的选择,因为只有在重分发之后才执行重复数据删除步骤。

简而言之,DISTINCT vs. GROUP BY在Teradata中的意思是:

GROUP BY ->用于多个重复 DISTINCT ->没有或只有几个重复项。 在使用DISTINCT时,有时会耗尽AMP上的线轴空间。原因是重新分配立即发生,倾斜可能会导致AMP耗尽空间。

如果发生这种情况,使用GROUP BY可能会有更好的机会,因为在第一步中已经删除了重复项,并且在amp之间移动的数据更少。