GROUP BY子句命令省略Oracle 11g查询中的结果

时间:2018-02-21 18:20:48

标签: sql oracle11g group-by

我有一个简单的查询似乎可以提供所需的结果:

select op.opr, op.last, op.dept, count(*) as counter 
from DWRVWR.BCA_M_OPRIDS1 op
where op.opr = '21B'
group by op.opr, op.last ,op.dept;

我的原始查询未返回任何结果。唯一的区别是group by子句的顺序:

select op.opr, op.last, op.dept, count(*) as counter 
from DWRVWR.BCA_M_OPRIDS1 op
where op.opr = '21B'
group by op.opr, op.dept, op.last;

实际上,这是一个更大,更复杂的查询的一部分,但我把问题缩小到了这个范围。我能够找到的所有文档都说明group by子句的顺序无关紧要。我真的想了解为什么我会得到不同的结果,因为如果存在潜在问题,我将不得不审查所有使用group by子句的查询。我正在使用SQL Developer,如果重要的话。

另外,如果group by子句的顺序无关紧要,并且需要在group by子句中列出聚合函数中未使用的每个字段,group by子句是否只是冗余而且看似不必要?

1 个答案:

答案 0 :(得分:2)

  

我能够找到的所有文档都说明group by子句的顺序无关紧要

这不完全正确,这取决于。

分组功能不受GROUP BY子句中列顺序的影响。无论顺序如何,它都将生成相同的组集。也许那就是你发现的那些文件所指的那些。但是,顺序对其他方面很重要。

在Oracle 10g之前,GROUP BY隐式执行ORDER BY,因此GROUP BY子句中列的顺序确实很重要。组集是相同的,但只是以不同的方式排序。从Oracle10g开始,如果希望结果集按任何特定顺序排列,则必须添加ORDER BY子句。其他数据库也有类似的历史。

订单重要的另一种情况是表格上有索引。仅当列与GROUP BYORDER BY子句中指定的列完全匹配时,才使用多列索引。因此,如果您更改订单,您的查询将不会使用索引,并将执行不同的操作。结果是一样的,但性能不是。

如果您使用GROUP BY等功能,ROLLUP子句中列的顺序也很重要。这次结果本身不会是一样的。

建议遵循按层次结构顺序列出GROUP BY子句中字段的最佳做法。这使查询更具可读性,更易于维护。

  

另外,如果group by子句的顺序无关紧要,并且需要在group by子句中列出聚合函数中未使用的每个字段,group by子句是否只是冗余而且看似不必要?

不,GROUP BY子句在标准SQL和Oracle中是必需的。如果要将聚合函数应用于整个结果集,则只有一个例外可以省略GROUP BY子句。在这种情况下,您的SELECT列表必须仅包含聚合表达式。