是否有任何解决方法可以在特定间隔范围的窗口内使用MEDIAN函数?我想用途:
MEDIAN(numcolumn) OVER (PARTITION BY a
ORDER BY date_b RANGE BETWEEN INTERVAL '30' DAY PRECEDING AND CURRENT ROW
)
Oracle抛出一个错误,因为不允许在这里使用ORDER BY。本声明与AVG合作。有没有什么快速的方法可以让这个窗口函数工作,而不是使用一些缓慢的内部连接来处理大量的数据?
2条答案
按热度按时间2w3rbyxf1#
这个问题已经被问过很多次了,但是快速回顾一下,我还没有找到一个令人满意的答案。Oracle不允许在
MEDIAN
中使用ORDER BY
子句(尽管它允许在AVG
中使用!许多人评论说这是没有意义的,因为MEDIAN
从一个无序集合中计算结果,对它进行排序将不会完成任何事情,但这忽略了重要的一点,即为了进行范围窗口(如运行平均值,运行中位数等),您需要指定顺序以创建范围逻辑。因此,不支持ORDER BY
意味着您无法像您正在尝试的那样使用ROWS BETWEEN
,这是Oracle功能中的一个差距。也许在未来的版本中,他们会解决这个问题。为了实现你所需要的,我建议如下:
只要确保您在
tbl(a,date_b,numcolumn)
上有索引即可thigvfpy2#
由于
median
没有公开为具有完整窗口语法支持的分析函数,因此不能将其与窗口规范子句一起使用。但是,这种限制通常可以使用
model
子句来推动,在单元格计算中可以使用(不太严格的)聚合函数。使用偏移量模拟
median
解析函数的步骤:partition by
列放在model
的相应子句中。order by
列放入dimension by
子句中。您将能够通过cv(dimension_name)
函数使用这些维度的当前(根据当前处理的行)值指定这些列的相对限制。unique single reference
以忽略有关单元格寻址不唯一的抱怨:我们希望处理逻辑间隔(range between
),而不是物理间隔。row_number
函数,按所需表达式排序为dimension by
。它将允许偏移这个值,相当于rows between
(只要每个分区的行号是唯一的)。partition by
和dimension by
的表达式作为measures
子句:您不必为它们指定规则,但它会将它们暴露给select
列表和rules
表达式的右侧。measures
:它会保留结果。将所有这些结合在一起,我们将使用
date_column between cv(date_column) - interval '30' day and CV(date_column)
作为计算的参考单元格,并使用median
作为该范围内的聚合函数。结果查询
为随机生成的数据集(由前三列表示)和5天窗口返回此结果:
| ID| DT|瓦尔|MED|
| --------------|--------------|--------------|--------------|
| 0| 2023-05-10 2023-05-10 2023-05-10|-1|-1|
| 0| 2023-05-12 2023-05-12 2023-05-12|二|二|
| 0| 2023-05-12 2023-05-12 2023-05-12|三|二|
| 0| 2023-05-16 2023-05-16 2023-05-16|五|三|
| 0| 2023-05-17 2023-05-17 2023-05-17|-4个|二点五|
| 0| 2023-05-19 2023-05-19 2023-05-19|六|五|
| 0| 2023-05-24 2023-05-24|-7| -0.5|
| 0| 2023-06-01 2023-06-01 2023-06-01|八|八|
| 0| 2023-06-04 2023-06-04|九|八点五|
| 1| 2023-05-26 2023-05-26|十二岁|十二岁|
| 1| 2023-05-28 2023-05-28 2023-05-28|-16|-2|
| 1| 2023-05-29 2023-05-29 2023-05-29|-19|-16|
| 1| 2023-06-02 2023-06-02|-13|-16|
| 1| 2023-06-03 2023-06-03|十八岁|-1|
| 1| 2023-06-03 2023-06-03|十一|-1|
| 1| 2023-06-04 2023-06-04|十四岁|十二点五|
| 1| 2023-06- 05 2023-06-05 2023-06-05|-10|十一|
| 1| 2023-06- 10 2023-06-10 2023-06-10|十五岁|二点五|
| 1| 2023-06- 12 2023-06-12 2023-06-12| 17个|十六岁|
| 二|2023-06-04 2023-06-04|二十一|二十一|
| 二|2023-06- 10 2023-06-10 2023-06-10|二十六|二十六|
| 二|2023-06-30 - 2023-06-30|二十|二十|
| 二|2023-07-01 2023-07-01|二十三|二十一点五|
| 二|2023-07-04 2023-07-04|二十九|二十三|
| 二|2023-07-06 2023-07-06|二十八|二十三|
| 二|2023-07-12 2023-07-12|二十四|1|
| 二|2023-07-12 2023-07-12|二十二|1|
| 二|2023-07-16 2023-07-16 2023-07-16|二十七个|二十四|
| 二|2023-07-18 2023-07-18 2023-07-18|二十五|1|
fiddle