我有一个简单的查询似乎可以提供所需的结果:
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子句是否只是冗余而且看似不必要?
答案 0 :(得分:2)
我能够找到的所有文档都说明group by子句的顺序无关紧要
这不完全正确,这取决于。
分组功能不受GROUP BY
子句中列顺序的影响。无论顺序如何,它都将生成相同的组集。也许那就是你发现的那些文件所指的那些。但是,顺序对其他方面很重要。
在Oracle 10g之前,GROUP BY
隐式执行ORDER BY
,因此GROUP BY
子句中列的顺序确实很重要。组集是相同的,但只是以不同的方式排序。从Oracle10g开始,如果希望结果集按任何特定顺序排列,则必须添加ORDER BY
子句。其他数据库也有类似的历史。
订单重要的另一种情况是表格上有索引。仅当列与GROUP BY
或ORDER BY
子句中指定的列完全匹配时,才使用多列索引。因此,如果您更改订单,您的查询将不会使用索引,并将执行不同的操作。结果是一样的,但性能不是。
如果您使用GROUP BY
等功能,ROLLUP
子句中列的顺序也很重要。这次结果本身不会是一样的。
建议遵循按层次结构顺序列出GROUP BY
子句中字段的最佳做法。这使查询更具可读性,更易于维护。
另外,如果group by子句的顺序无关紧要,并且需要在group by子句中列出聚合函数中未使用的每个字段,group by子句是否只是冗余而且看似不必要?
不,GROUP BY
子句在标准SQL和Oracle中是必需的。如果要将聚合函数应用于整个结果集,则只有一个例外可以省略GROUP BY
子句。在这种情况下,您的SELECT
列表必须仅包含聚合表达式。