填写日期之间的空白

时间:2017-05-05 15:48:57

标签: sql sql-server

我需要填写表格中的NULL空白。每个ID(x)可以有多个CKD_STAGE,但有几个月有空值,我想用最新的已知CKD_STAGE填充其间的空格。这是我到目前为止所拥有的。

SELECT DISTINCT DOS, x, CKD_STAGE, REF_YEAR
FROM #CKD_MM

 DECLARE @MAXDOS INT = (SELECT MAX(DOS) FROM #CKD_MM)
 DECLARE @MINDOS INT = (SELECT MIN(DOS) FROM #CKD_MM) 

 Update #CKD_MM
 set CKD_STAGE = @MAXDOS
 WHERE CKD_STAGE is null
      AND DOS BETWEEN @MAXDOS AND  @MINDOS

我的逻辑是找到不同的x id并查看每个唯一ID的日期(DOS)和CKD_Stage。查看每个ckd_stage的最大和最小日期,并用最大值填充其间的间隙。程序运行但我仍然得到NULL值。

以下是使用其中一个id

表格的快照
DOS     x         CKD_STAGE REF_YEAR
201405  480000000   2       2014
201510  480000000   NULL    2015
201504  480000000   NULL    2015
201506  480000000   NULL    2015
201512  480000000   NULL    2015
201511  480000000   NULL    2015
201409  480000000   2       2014
201509  480000000   3       2015
201507  480000000   NULL    2015
201404  480000000   NULL    2014
201501  480000000   NULL    2015
201411  480000000   NULL    2014
201402  480000000   NULL    2014
201503  480000000   NULL    2015

所以我需要所有NULLS,201509之前的日期为2,而201509之后的所有日期为3.我有1000个记录,所以我需要这个来处理一系列不同的ID和不同的CKD_STAGES。

2 个答案:

答案 0 :(得分:0)

如果我理解正确,你想要将空值列设置为2,如果它在dos列值201509之前,则设置为3,如果它在201509之后。

{{1}}

答案 1 :(得分:0)

使用apply()获取给定null的上一个和下一个非x

select 
    t.dos
  , t.x 
  , coalesce(t.ckd_stage,prev.ckd_stage,nxt.ckd_stage) as ckd_stage
  , t.ref_year
from t
  outer apply (
    select top 1 i.ckd_stage
    from t i
    where i.x = t.x
      and i.dos > t.dos
      and i.ckd_stage is not null
    order by i.dos asc
  ) nxt
 outer apply (
    select top 1 i.ckd_stage
    from t i
    where i.x = t.x
      and i.dos < t.dos
      and i.ckd_stage is not null
    order by i.dos desc
  ) prev
order by t.dos

作为update

update t
set ckd_stage = coalesce(prev.ckd_stage,nxt.ckd_stage)
from  t
  outer apply (
    select top 1 i.ckd_stage
    from t i
    where i.x = t.x
      and i.dos > t.dos
      and i.ckd_stage is not null
    order by i.dos asc
  ) nxt
 outer apply (
    select top 1 i.ckd_stage
    from t i
    where i.x = t.x
      and i.dos < t.dos
      and i.ckd_stage is not null
    order by i.dos desc
  ) prev
where t.ckd_stage is null

select * 
from t 
order by dos

rextester演示:http://rextester.com/YFTM98118

返回:

+--------+-----------+-----------+----------+
|  dos   |     x     | ckd_stage | ref_year |
+--------+-----------+-----------+----------+
| 201402 | 480000000 | 2         |     2014 |
| 201404 | 480000000 | 2         |     2014 |
| 201405 | 480000000 | 2         |     2014 |
| 201409 | 480000000 | 2         |     2014 |
| 201411 | 480000000 | 2         |     2014 |
| 201501 | 480000000 | 2         |     2015 |
| 201503 | 480000000 | 2         |     2015 |
| 201504 | 480000000 | 2         |     2015 |
| 201506 | 480000000 | 2         |     2015 |
| 201507 | 480000000 | 2         |     2015 |
| 201509 | 480000000 | 3         |     2015 |
| 201510 | 480000000 | 3         |     2015 |
| 201511 | 480000000 | 3         |     2015 |
| 201512 | 480000000 | 3         |     2015 |
+--------+-----------+-----------+----------+