2014-01-09 69 views
0

我想我理解它是如何工作的,但现在我感到困惑。FIRST_VALUE函数不能按预期工作

我有一个数据集:

id date  value 
1 20080101 null 
2 20090101 34 
3 20100101 null 

三个记录,从2008年1月,2009年和2010年。现在,我想创建一个新列“值2”与最新的非空值。基本上我想要一个有3个34的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.这是怎么回事错在这里?

+1

我从http://stackoverflow.com/questions/1228910/找到了答案什么,错用,此一价值查询 – Steve

回答

0

尝试通过条款

消除顺序空衣被合计一种可能的解决方案可能是

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 
0

你忘记了窗外。缺省值是无界前沿和当前行之间的范围,意味着您的值正在从第一行到当前行的窗口中查找。你的排序行是:

id date  value 
3 20100101 null 
2 20090101 34 
1 20080101 null 
  • 对于ID为1的记录,3,2,1是关注的焦点。值34在第二行中找到。
  • 对于id 2,记录3和2处于焦点。值34在第二行中找到。
  • 对于id 3,只有记录3处于焦点。因此无法找到值34。

顺便说一句:你的请求中有一个错字:它是first_value(值忽略空值),而不是first_value(值)忽略空值。

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 
相关问题