【问题标题】:GROUP BY clause order omitting results in Oracle 11g queryOracle 11g 查询中的 GROUP BY 子句顺序省略结果
【发布时间】:2018-08-01 10:42:57
【问题描述】:

我有一个简单的查询,似乎给出了预期的结果:

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 子句是否只是多余且看似不必要的?

【问题讨论】:

  • 我昨天确实遇到了这个问题,但是在 SQL Server 中。我的问题是我尝试订购的日期和分组依据不是我正在搜索的信息。也许它与物理数据本身有关,而不是 ORDER 或 GROUP BY 子句。
  • 听起来像一个错误。又似曾相识,但不知从何而来。你在哪个补丁级别?它是一个简单的表格还是一个视图?这两个查询的执行计划也可能很有趣。

标签: sql oracle11g group-by


【解决方案1】:

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

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

分组功能不受GROUP BY 子句中列顺序的影响。无论顺序如何,它都会产生相同的组集。也许这就是您找到的那些文档所指的内容。但是顺序对于其他方面确实很重要。

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

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

如果您使用ROLLUP 之类的某些功能,GROUP BY 子句中的列顺序也很重要。这一次结果本身将不一样。

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

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

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

【讨论】:

  • 嗨拉西尔。我指的是您指定的文档。该文档指出,“无论顺序如何,它都会产生相同的组集。”但我的问题具体是关于为什么它没有产生相同的组集。我知道 ROLLUP 和 CUBE 异常。我没有想到索引部分,但这是一个没有索引的视图,无论如何,它不应该改变结果。
  • 索引是在表上定义的,但是视图可以像任何查询一样使用它们。是的,从返回相同记录的意义上说,这不应该改变结果。但是,您说这个“是一个更大、更复杂的查询的一部分”,所以如果在您更改GROUP BY 子句中列的顺序时更改了排序,并且该顺序影响了较大查询的其余部分,那么您最终可能会得到不同的结果。如果不查看整个查询以及可能的环境,任何人都无法回答您问题的这一部分。
  • 我的意思是原来查询要大得多,但我通过削减它发现了问题。我看到发布的两个查询的问题。我检查了视图上没有索引。你是说即使我看不到优化器会意识到原始表已被索引并使用它的索引?它怎么可能知道有一个多列索引?如果这些列已排序,它是否只是假设一个索引?
  • 所以你是说如果你完全按照你在问题中发布的那样单独运行这两个查询,它们会返回不同的结果?直接将它们作为查询运行,而不是在视图中。如果它们仍然返回不同的结果,请检查并比较它们的执行计划。执行计划会告诉您使用了哪些索引(如果有)。
  • 是的,这正是我想说的。不幸的是,我似乎在这里可能遇到了死胡同,因为我无法访问表格本身,我没有必要的特权来制定解释计划。我只是视图的最终用户(业务分析师),而不是 DBA 或开发人员。我假设我不能做解释计划,因为我有只读权限。不过,我感谢您的时间和精力,并将您的答案标记为完整,因为我无法为您提供提供完整答案所需的详细信息。
猜你喜欢
  • 1970-01-01
  • 2023-04-04
  • 1970-01-01
  • 1970-01-01
  • 2012-01-02
  • 2012-04-20
  • 2015-10-23
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多