我以为我理解它是如何运作的,但现在我很困惑。
我有一个数据集:
id date value
1 20080101 null
2 20090101 34
3 20100101 null
从2008年1月,2009年和2010年开始的三条记录。现在我想创建一个具有最新非null值的新列“value2”。基本上我想要一个3个34s的value2列。我写道:
select id, date, value, first_value(value) ignore nulls over (order by date desc) as value2 from table
然而,我得到了:
id date value value2
1 20080101 null 34
2 20090101 34 34
3 20100101 null null
最后一个值仍为空而不是34.这里出了什么问题?
答案 0 :(得分:1)
分析函数的默认窗口为ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW
,如果您将其更改为ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING
,那么您将获得所需的结果:
查询1
WITH table_name AS (
SELECT 1 AS id, TO_DATE( '20080101', 'YYYYMMDD' ) AS "date", NULL AS value FROM DUAL
UNION ALL SELECT 2, TO_DATE( '20090101', 'YYYYMMDD' ), 34 FROM DUAL
UNION ALL SELECT 3, TO_DATE( '20100101', 'YYYYMMDD' ), NULL FROM DUAL
)
SELECT id,
"date",
value,
FIRST_VALUE( value IGNORE NULLS ) OVER (ORDER BY "date" DESC ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING ) AS value2
FROM table_name;
<强>结果
ID | date | VALUE | VALUE2
-------------------------------------------------
3 | 2010-01-01 00:00:00 | (null) | 34
2 | 2009-01-01 00:00:00 | 34 | 34
1 | 2008-01-01 00:00:00 | (null) | 34
答案 1 :(得分:0)
尝试删除order by子句
中的空值可能的解决方案可能是
with x as (
select 1 as id , 20080101 as ddate , null as v from dual union all
select 2 , 20090101 ,34 from dual union all
select 3 , 20100101 ,null from dual union all
select 4 , 20090101 ,15 from dual union all
select 5 , 20110101 ,null from dual union all
select 6 , 20120101 ,null from dual union all
select 7 , 20030101 ,55 from dual
)
select x.* ,
first_value(v) over (order by case when v is null then null else ddate end) as last_nn_v
from x
order by ddate
/
ID DDATE V LAST_NN_V
---------- ---------- ---------- ----------
7 20030101 55 55
1 20080101 55
4 20090101 15 55
2 20090101 34 55
3 20100101 55
5 20110101 55
6 20120101 55
答案 2 :(得分:0)
你忘记了窗户。默认值是UNBOUNDED PRECEDING和CURRENT ROW之间的范围,意味着您的值正在从第一行到当前行的窗口中查找。您的排序行是:
id date value
3 20100101 null
2 20090101 34
1 20080101 null
BTW:你的请求中有一个拼写错误:它是first_value(值忽略空值),而不是first_value(value)忽略空值。