无法在 Oracle 的窗口函数中使用 ORDER BY 子句

Posted

技术标签:

【中文标题】无法在 Oracle 的窗口函数中使用 ORDER BY 子句【英文标题】:Unable to user an ORDER BY clause in a window function with Oracle 【发布时间】:2016-12-17 01:52:52 【问题描述】:

我有一个在窗口函数中没有ORDER BY 子句的查询可以正常工作:

select
"TABLE_NAME",
"DENSITY",
"NUM_DISTINCT",
ROWNUM,
median(DENSITY) OVER (PARTITION BY table_name )
from ALL_TAB_COLUMNS a
where 1=1
and owner = 'SYS'
and table_name='CARRY'
and "NUM_DISTINCT" < 1000
and DENSITY < 1
AND num_nulls = 0

但我绝对需要这个order by 子句来获取我需要的格式的数据。如果我添加order by,我会收到这个奇怪的错误消息:

ORA-30487: ORDER BY not allowed here
30487. 00000 -  "ORDER BY not allowed here"
*Cause:    DISTINCT functions and RATIO_TO_REPORT cannot have an ORDER BY
*Action:
Error at Line: 6 Column: 47

下面是完整的 SQL,顺序如下:

select
"TABLE_NAME",
"DENSITY",
"NUM_DISTINCT",
ROWNUM,
median(DENSITY) OVER (PARTITION BY table_name ORDER BY "DENSITY")
from ALL_TAB_COLUMNS a
where 1=1
and owner = 'DEANZA'
and table_name='CARRIER_A'
and "NUM_DISTINCT" < 1000
and DENSITY < 1
AND num_nulls = 0

【问题讨论】:

不,您绝对不需要在 MEDIAN(...) 函数中使用 ORDER BY。你了解 MEDIAN 是做什么的吗?您需要什么 - 对于第三行,您需要前三个密度值的中值密度,然后对于第十行 - 前十个密度值的中值等?你可能需要它来做什么? ORDER BY DENSITY 放在查询的末尾,而不是放在MEDIAN 计算中。您不能在 MEDIAN 分析函数中使用 ORDER BY - 当您在允许它的分析函数中使用 ORDER BY 时,它与您的结果排序无关。 你想完成什么?样本数据和期望的结果对沟通有很大帮助。 【参考方案1】:

如documentation 中所述,对于MEDIAN,您不能在其OVER 子句中使用ORDER BY

MEDIAN 将采用数值或日期时间值并返回中间值或插值值,一旦值被排序,该值将成为中间值。所以无论如何都不需要使用ORDER BY

【讨论】:

您了解 ORDER BY 在分析函数中的作用吗?它与对整个分区的排序无关。 是的,我猜 OP 认为 MEDIAN 不会先对数据进行排序。 order by 对于使用 rows between 3 preceding and 1 preceding 的窗口很有用。

以上是关于无法在 Oracle 的窗口函数中使用 ORDER BY 子句的主要内容,如果未能解决你的问题,请参考以下文章

使用具有不同 order by 子句的 postgres 窗口函数

使用窗口函数计算滚动计数

Sql server - 窗口函数只能出现在 SELECT 或 ORDER BY 子句中

没有 ORDER BY 的窗口函数

窗口函数只能出现在 SELECT 或 ORDER BY 子句中--update in cursor

oracle使用order by排序null值如何处理?