由于 ORDER BY 子句,Partition By Clause 给出不同的结果
Posted
技术标签:
【中文标题】由于 ORDER BY 子句,Partition By Clause 给出不同的结果【英文标题】:Partition By Clause is giving different results due to ORDER BY clause 【发布时间】:2012-04-25 17:04:36 【问题描述】:我正在尝试对样本数据运行分区查询。如果我删除 ORDER BY 子句,它会给我不同的结果。不同结果的原因是什么。请查看以下链接。
http://www.sqlfiddle.com/#!4/a0f10/5
SELECT MAX(B1.ET) OVER(PARTITION BY B1.MAS_DIV_KEY,B1.STN_KEY,B1.SBSC_GUID_KEY ORDER BY B1.ST)AS TEST_COL
FROM AM_PROGRAM_TUNING_EVENT_TMP1 B1;
SELECT MAX(B1.ET) OVER(PARTITION BY B1.MAS_DIV_KEY,B1.STN_KEY,B1.SBSC_GUID_KEY)AS TEST_COL1
FROM AM_PROGRAM_TUNING_EVENT_TMP1 B1;
【问题讨论】:
您在查询中的哪个位置使用了ORDER BY
?
哪个查询?护目镜;他们什么都不做......
让我在这里发布查询...
我看不出这些结果有什么不同
@Lamak 看到这个sqlfiddle.com/#!4/a0f10/6 - 第一个查询中的第一条记录是11:05;其余记录是 11:50
【参考方案1】:
当您在 OVER() 子句中对通常对排序不敏感的聚合(最小值、最大值、标准差等)进行排序时,它会变成一个运行小计。请参阅 Justin Cave 对以下问题的回答以获得更彻底的处理。
Oracle MIN as analytic function - odd behavior with ORDER BY?
编辑
这里参考sqlfiddle:
http://www.sqlfiddle.com/#!4/a0f10/33
第一个查询:
SELECT B1.ST
, B1.ET
, MAX(B1.ET)
OVER(PARTITION BY B1.MAS_DIV_KEY
,B1.STN_KEY
,B1.SBSC_GUID_KEY
ORDER BY B1.ST
) AS TEST_COL
FROM AM_PROGRAM_TUNING_EVENT_TMP1 B1
ORDER BY B1.ST;
...返回
ST ET TEST_COL
March, 28 2012 11:00:00-0700 March, 28 2012 11:05:00-0700 March, 28 2012 11:05:00-0700
March, 28 2012 11:03:00-0700 March, 28 2012 11:15:00-0700 March, 28 2012 11:50:00-0700
March, 28 2012 11:03:00-0700 March, 28 2012 11:50:00-0700 March, 28 2012 11:50:00-0700
March, 28 2012 11:10:00-0700 March, 28 2012 11:30:00-0700 March, 28 2012 11:50:00-0700
March, 28 2012 11:20:00-0700 March, 28 2012 11:50:00-0700 March, 28 2012 11:50:00-0700
所以让我们分解一下……第一行是一个不同的 ST,所以到该点的 MAX 是该行中的任何内容。下一行,ST 不是唯一的。因此,截至该点的所有行的 MAX 不是 11:15,而是 ST 11:03 的两行的 11:50。最后两行在 11:50 之后永远不会有 ET,所以这就是我们为所有剩余行显示的内容。我们在 OVER 子句中使用了 ORDER BY,这就是我们告诉 Oracle 要做的事情。
【讨论】:
正如 arturro 指出的那样,分析函数的默认范围将是基于 ORDER BY 中的排序的所有先前行的相关行。如果您添加 RANGE BETWEEN UNBOUNDED PRECEDING 和 UNBOUNDED FOLLOWING,您应该得到与没有 ORDER BY 相同的结果。【参考方案2】:甲骨文documentation for analytic functions 说:
*If you omit the windowing_clause entirely, then the default is RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW.*
如果您了解 RANGE 的工作原理,您应该很清楚为什么会看到这样的结果。
【讨论】:
以上是关于由于 ORDER BY 子句,Partition By Clause 给出不同的结果的主要内容,如果未能解决你的问题,请参考以下文章
转转转---ROWNUMBER() OVER( PARTITION BY COL1 ORDER BY COL2)用法
ROWNUMBER() OVER( PARTITION BY COL1 ORDER BY COL2)用法,先分组,然后在组内排名,分组计算等
rank() over(partition by A order by B) MySQL里可以partition多个字段嘛