car*_*ose 10 sql oracle window-functions
我不明白为什么ORDER BY在分析COUNT函数中使用子句时会有不同的结果.
使用一个简单的例子:
with req as
(select 1 as n, 'A' as cls
from dual
union
select 2 as n, 'A' as cls
from dual)
select req.*, count(*) over(partition by cls) as cnt from req;
Run Code Online (Sandbox Code Playgroud)
给出以下结果:
N CLS CNT
2 A 2
1 A 2
Run Code Online (Sandbox Code Playgroud)
然而,当ORDER BY在分析子句中添加一个时,结果是不同的!
with req as
(select 1 as n, 'A' as cls
from dual
union
select 2 as n, 'A' as cls
from dual)
select req.*, count(*) over(partition by cls order by n) as cnt from req;
Run Code Online (Sandbox Code Playgroud)
CNT专栏改变了:
N CLS CNT
1 A 1
2 A 2
Run Code Online (Sandbox Code Playgroud)
有人可以解释一下吗?
谢谢
首先,链接到文档.然而,这有点模糊.
分析条款包括query_partition_clause,order_by_clause和windowing_clause.而且,一个非常重要的事情windowing_clause是
除非已指定,否则不能指定此子句
order_by_clause.该RANGE子句定义的某些窗口边界允许您仅指定一个表达式order_by_clause.请参阅"ORDER BY子句的限制".
但是,不仅可以不使用windowing_clause不order_by_clause,他们是联系在一起的.
如果完全省略windowing_clause,则默认为
RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW.
默认的窗口子句产生类似于运行总计的内容.COUNT返回1第一行,因为窗口顶部和当前行之间只有一行,2第二行依此类推,依此类推.
因此,在您的第一个查询中根本没有窗口,但在第二个查询中有默认窗口.
您可以通过指定完全无界窗口来模拟第一个查询的行为.
with req as
(select 1 as n, 'A' as cls
from dual
union
select 2 as n, 'A' as cls
from dual)
select req.*, count(*) over(partition by cls order by n RANGE BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) as cnt from req;
Run Code Online (Sandbox Code Playgroud)
是的
N CLS CNT
1 A 2
2 A 2
Run Code Online (Sandbox Code Playgroud)
考虑这一点的最简单方法 - 将ORDER BYout 排除在外相当于以分区中的所有行彼此“相等”的方式“排序”。实际上,您可以通过显式添加这样的ORDER BY子句来获得相同的效果:( ORDER BY 0或“order by”任何常量表达式),或者甚至更强调的是,ORDER BY NULL.
为什么你得到整个分区的COUNT()或SUM()等与默认的窗口子句有关:RANGE between unbounded preceding and current row. “范围”(相对于“ROWS”)意味着所有与当前行“绑定”的行也包括在内,即使它们不在它之前。由于所有行都是绑定的,这意味着包括整个分区,无论哪一行是“当前”。
| 归档时间: |
|
| 查看次数: |
2451 次 |
| 最近记录: |