查询如下:
with t
as (
select 450 id, null txt , 3488 id_usr from dual union all
select 449 , null , 3488 from dual union all
select 79 , 'A' , 3488 from dual union all
select 78 , 'X' , 3488 from dual
)
select id
, txt
, id_usr
, first_value(txt ignore nulls) over (partition by id_usr order by id desc) first_one
from t
并返回:
ID TXT D_USR FIRST_ONE
450 3488
449 3488
79 A 3488 A
78 X 3488 A
这是预期的:
ID TXT ID_USR FIRST_ONE
450 3488 A
449 3488 A
79 A 3488 A
78 X 3488 A
出了什么问题?为什么?
答案 0 :(得分:7)
RANGE / ROWS
的默认FIRST_VALUE
(与任何其他分析函数一样)为BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW
。
如果您添加IGNORE NULLS
,则在构建范围时不会考虑NULL
值。
RANGE
变为BETWEEEN UNBOUNDED PRECEDING AND CURRENT ROW EXCEPT FOR THE NULL ROWS
(它不是有效的OVER
条款。)
由于txt
的{{1}} NULL
高id
,因此首先选择它们,并且它们的范围为空,因为没有非NULL
它们之间的行和UNBOUNDED PRECEDING
您应该更改查询的ORDER BY
或RANGE
子句。
更改ORDER BY
会将带有NULL
id的行放到窗口的末尾,以便始终首先选择非NULL
值(如果有),并{{1} 1}}将保证从该值开始:
RANGE
更改with t
as (
select 450 id, null txt , 3488 id_usr from dual union all
select 449 , null , 3488 from dual union all
select 79 , 'A' , 3488 from dual union all
select 78 , 'X' , 3488 from dual
)
select id
, txt
, id_usr
, first_value(txt) over (partition by id_usr order by NVL2(TXT, NULL, id) DESC) first_one
from t
重新定义范围以包括分区中的所有非RANGE
行:
NULL