Oracle SQL - 根据以前的记录填充列,并保留没有先前数据的记录NULL

时间:2014-08-20 15:10:34

标签: sql oracle

我在表格中设置了一些列:

ID      IDSEQUENCENUM   DATE
1       1               20050101
1       2               
1       3               
1       4               20050505
2       1               20120303
2       2               20120404
2       3               
3       1               
3       2
3       3               20140505
...

我需要做的是当Date为null时将其填入该ID中的先前IDSEQUENCENUM。如果该ID / IDSEQUENCENUM没有先前的日期,则保持为空。所以上面的内容后面会是这样的:

ID      IDSEQUENCENUM   DATE
1       1               20050101
1       2               20050101
1       3               20050101
1       4               20050505
2       1               20120303
2       2               20120404
2       3               20120404
3       1               
3       2
3       3               20140505
...

没有说每个记录之间DATE的Null值有多少。

感谢您的帮助!

(哦,如果您好奇,由于使用此数据的程序需要接受日期,因此日期为varchar2格式)

2 个答案:

答案 0 :(得分:3)

我认为这是你正在寻找的,遵循上一个答案:

select id, idseq, 
       case when dateval is null then last_value(dateval) ignore nulls over (partition by id order by idseq) else dateval
       end as dateval
from dates
order by id, idseq;

对于更新更改,请执行以下操作:

merge into dates dt2 using 
(
select id, idseq, 
       case when dateval is null then last_value(dateval) ignore nulls over (partition by id order by idseq) else dateval
       end as dateval
from dates
order by id, idseq
) dt
on (DT2.ID = dt.id and DT2.IDSEQ = dt.idseq )
when matched then
update set DT2.DATEVAL = dt.dateval

我希望它有所帮助。

答案 1 :(得分:1)

以下查询可以获得预期的结果(使用a_horse_with_no_name的列和表名称)

select 
  s1.id,
  s1.idsequencenum, 
  case
    when s1.date_col is null then max(s2.date_col)
    else s1.date_col
  end modified_date_col
from simple s1
left outer join simple s2
on s2.id = s1.id and s2.idsequencenum < s1.idsequencenum and s2.date_col is not null --and s1.date_col is null
group by 
  s1.id,
  s1.idsequencenum, 
  s1.date_col
order by
  s1.id,
  s1.idsequencenum;

以下是执行更新的MERGE语句:

merge into simple s
using
(
  select 
    s1.id,
    s1.idsequencenum, 
    case
      when s1.date_col is null then max(s2.date_col)
      else s1.date_col
    end modified_date_col
  from simple s1
  left outer join simple s2
  on s2.id = s1.id and s2.idsequencenum < s1.idsequencenum and s2.date_col is not null --and s1.date_col is null
  group by 
    s1.id,
    s1.idsequencenum, 
    s1.date_col
) t
on (s.id = t.id and s.idsequencenum = t.idsequencenum)
when matched then
  update set s.date_col = t.modified_date_col;

已更新 SQL Fiddle demo