GROUP BY与ORDER BY结合使用

时间:2012-08-29 18:47:44

标签: sql oracle group-by sql-order-by

  

GROUP BY子句对行进行分组,但不一定按任何特定顺序对结果进行排序。要更改顺序,请使用GROUP BY子句后面的ORDER BY子句。 ORDER BY子句中使用的列必须出现在SELECT列表中,这与正常使用ORDER BY不同。 [Oracle示例,第四版,第274页]

为什么?为什么使用GROUP BY会影响SELECT子句中的必需列?

另外,在我不使用GROUP BY的情况下:为什么我要对某些列进行ORDER BY,然后只选择列的一个子集?

7 个答案:

答案 0 :(得分:6)

引用中的粗体文字不正确(在许多常见用例中可能过于简单化,但作为要求并不严格。)例如,虽然AVG(val)不在选择列表中,但此语句执行得很好:

WITH DATA AS (SELECT mod(LEVEL,3) grp, LEVEL val FROM dual CONNECT BY LEVEL < 100)
SELECT grp,MIN(val),MAX(val)
FROM DATA
GROUP BY grp
ORDER BY AVG(val)

ORDER BY子句中的表达式必须能够在GROUP BY的上下文中进行评估。例如,ORDER BY val在上面的示例中不起作用,因为表达式val对于分组产生的每一行都没有明确的值。

关于你的第二个问题,你可能关心排序,但不关心排序表达的价值。从选择列表中排除不需要的表达式会减少必须实际从服务器发送到客户端的数据量。

答案 1 :(得分:5)

实际上声明并不完全正确,正如Dave Costa的例子所示。

Oracle文档说可以使用表达式,但表达式必须基于选择列表中的列。

  

expr - expr 根据expr的值对行进行排序。表达式基于   选择列表中的列或表中的列,视图或物化视图中的列   FROM子句。来源:Oracle®数据库   SQL语言参考   11g第2版(11.2)   E26088-01   2011年9月。页19-33

来自同一工作页面19-13和19-33(PDF中的页面1355和1365)

enter image description here

enter image description here

http://docs.oracle.com/cd/E11882_01/server.112/e26088/statements_10002.htm#SQLRF01702

http://docs.oracle.com/cd/E11882_01/server.112/e26088/statements_10002.htm#i2171079

答案 2 :(得分:3)

首先:

group by的实现是一个创建一个结构与原始from子句(表视图或一些连接表)不同的新结果集的实现。结果集由选择的内容定义。

并非每个SQL RDBMS都有此限制,但始终要求订购的内容是非分组列(AVGSUM等)的聚合函数或一个列的分组,或在多个结果之上起作用(如添加两列),因为这是分组操作结果的逻辑要求。

第二

因为您只关心该列的订购。例如,您可能有一个畅销单曲的列表而没有给出他们的销售(NYT畅销书保留他们的数据的一些细节是秘密,但确实有一个排名列表)。当然,您可以通过选择该列然后不使用它来解决这个问题。

答案 3 :(得分:2)

样本表

sample.grades
Name   Grade    Score
Adam   A        95
Bob    A        97
Charlie C       75

使用GROUP BY进行第一次查询

Select grade, count(Grade) from sample.grades GROUP BY Grade

输出

Grade Count
A     2
C     1

使用

命令进行第二次查询
select Name, score from sample grades order by score

输出

Bob    A        97
Adam   A        95
Charlie C       75

使用GROUP BY和订购的第三个查询

Select grade, count(Grade) from sample.grades GROUP BY Grade desc

输出

Grade Count
A     2
C     1

一旦你开始使用像Count这样的东西,你必须有分组。你可以一起使用它们,但它们的用途非常不同,我希望这些例子清楚地显示出来。

为了尝试回答这个问题,为什么group会影响select部分中的项目,因为这就是group by的意思。如果不按该列分组,则无法对列进行计数。

第二个问题,为什么要订购但不选择所有列? 如果我想按分数排序,但不关心实际成绩甚至是我可能做的分数

select name from sample.grades order by score

输出

Name
Bob
Adam
Charlie

答案 4 :(得分:2)

数据在为ORDER BY排序之前汇总。

如果您尝试按任何其他列(不在列表或聚合函数中)排序,将使用什么值?订购时没有单一价值。

我相信您可以使用这些值的组合进行排序。所以你可以说:

order by a+b

如果a和b在组中。您无法引入SELECT中未提及的列。我相信你可以使用SELECT中没有提到的聚合函数。

答案 5 :(得分:0)

您希望看到哪些结果按选择列表中未列出的列排序,而不参加group by子句?在任何情况下,SELECT列表列中未提及的所有排序都将被省略,因此Oracle人员正确地添加了限制。

with c as (
select 1 id, 2 value from dual
union all
select 1 id, 3 value from dual
union all
select 2 id, 3 value from dual
)
select id
from c
group by id
order by count(*) desc

答案 6 :(得分:0)

这是我的理解

&#34; GROUP BY子句对行进行分组,但不一定按任何特定顺序对结果进行排序。&#34;

- &GT;您可以通过

使用Group by without order

&#34;要更改顺序,请使用ORDER BY子句,该子句遵循GROUP BY子句。&#34;

- &GT;使用主键通过defaut选择行,如果添加顺序,则必须在

之后添加

&#34; ORDER BY子句中使用的列必须出现在SELECT列表中,这与正常使用ORDER BY不同。&#34;