SQL:使用以前的时间帧值更新Null

时间:2016-08-02 14:13:51

标签: sql-server null sql-update

我目前在SQL中有一个结果表,显示一个人的地址在哪个时间段(大学学期)发生了变化这并不是每个时间段都会发生,因此有些行显示为无效,我预计需要这些更新("填写")每个后续时间段,直到输入新的地址更改

我包含了这两个ID,因为它们代表了我所看到的两种可能情况:

-ID 1234应填写前面的条款与序列1县(如此处所示)

-ID 5678应该根据以前加入的表格填写前面的条款和序列1县(在这种情况下为CLAY)

目前,我正在展示以下内容:

ID       TERM         COUNTY     SEQUENCE
------------------------------------------
1234     201308       null       null
1234     201401       null       null
1234     201408       ORANGE     1
1234     201501       null       null
1234     201505       null       null
1234     201508       OSCEOLA    3
1234     201601       null       null
5678     201301       null       null
5678     201305       null       null
5678     201308       ST JOHNS   3
5678     201401       null       null
5678     201405       null       null
5678     201408       null       null
5678     201501       null       null
5678     201505       DUVAL      4

我需要输出看起来像:

ID       TERM       COUNTY       SEQUENCE
---------------------------------------------
1234     201308     ORANGE       null
1234     201401     ORANGE       null
1234     201408     ORANGE       1
1234     201501     ORANGE       null
1234     201505     ORANGE       null
1234     201508     OSCEOLA      3
1234     201601     OSCEOLA      null
5678     201301     CLAY         null
5678     201305     CLAY         null
5678     201308     ST JOHNS     3
5678     201401     ST JOHNS     null
5678     201405     ST JOHNS     null
5678     201408     ST JOHNS     null
5678     201501     ST JOHNS     null
5678     201505     DUVAL        4

这是我第一次遇到像这样的更新条款需要,所以您可以提供的任何见解将不胜感激!

*我不确定以前的代码中有多少是相关的,但这里基本上是输入最终输出的临时表代码(" PIDM"是ID):

DROP TABLE #ADDRESS_PT_1--, #ADDRESS_PT_2
GO

SELECT SPRADDR_PIDM 'PIDM', Y.TERM, SPRADDR_SEQNO 'SEQNO', SPRADDR_STAT_CODE 'STATE', SPRADDR_CNTY_CODE 'CNTY', 
BANNR_TERM = CASE
  WHEN Y2.TERM IS NULL THEN Y.TERM
  ELSE Y2.TERM
  END
INTO #ADDRESS_PT_1
FROM SPRADDR 
LEFT OUTER JOIN RCACYR Y2
  ON (SPRADDR_ACTIVITY_DATE BETWEEN Y2.BEGIN_DATE AND Y2.END_DATE
      AND SUBSTRING(Y2.TERM,5,2) IN ('50','80','10')),
    RCACYR Y
WHERE SPRADDR_ACTIVITY_DATE BETWEEN Y.BEGIN_DATE AND Y.END_DATE
  AND SUBSTRING(Y.TERM,5,2) IN ('05','08','01')
  AND SPRADDR_ATYP_CODE = 'MA'
ORDER BY SPRADDR_PIDM, SPRADDR_SEQNO
GO

/* Get the individuals addresses for each term */
SELECT *
--INTO #ADDRESS_PT_2
FROM #ADDRESS_PT_1 X
LEFT JOIN RCCNTY C 
    ON C.COUNTY = X.CNTY
WHERE X.SEQNO = (SELECT MAX(A.SEQNO)
                  FROM #ADDRESS_PT_1 A
                  WHERE X.PIDM = A.PIDM
                                        AND X.TERM = A.TERM)
    --AND X.PIDM = 5678
ORDER BY X.PIDM, X.SEQNO
GO

这个输出是:

PIDM    TERM    SEQNO   STATE   CNTY    BANNR_TERM  COUNTY  COUNTY_TITLE    COUNTY_REGION   COUNTY_REGION_TITLE
5678    201108  1       FL      CLAY    201108      CLAY    CLAY            2               Northeast Florida   
5678    201308  3       FL      ST J    201308      ST J    ST. JOHNS       2               Northeast Florida   
5678    201505  5       FL      DUVA    201550      DUVA    DUVAL           2               Duval County        

2 个答案:

答案 0 :(得分:1)

我在CTE中提供了您提供的样本。然后我外部应用(p)上一行,其中NOT NULL COUNTY,另一个外部应用,获取每个[SEQUENCE] = 1 ID的行。在最后的OUTER APPLY中使用表{(1}})而不是FROM cte,而FROM SPRADDR行可能不在CTE中。

[SEQUENCE] = 1

会给你:

;WITH cte AS (
SELECT * 
FROM (VALUES
(1234,     201308,       null,       null),
(1234,     201401,       null,       null),
(1234,     201408,       'ORANGE',     1),
(1234,     201501,       null,       null),
(1234,     201505,       null,       null),
(1234,     201508,       'OSCEOLA',    3),
(1234,     201601,       null,       null),
(5678,     201301,       null,       null),
(5678,     201305,       null,       null),
(5678,     201308,       'ST JOHNS',   3),
(5678,     201401,       null,       null),
(5678,     201405,       null,       null),
(5678,     201408,       null,       null),
(5678,     201501,       null,       null),
(5678,     201505,       'DUVAL',      4)
) as t(ID, TERM, COUNTY, [SEQUENCE])
)

SELECT  c.ID,
        c.TERM,
        COALESCE(c.COUNTY,p.COUNTY,p1.COUNTY) as COUNTY,
        c.[SEQUENCE]
FROM cte c
OUTER APPLY (
    SELECT TOP 1 COUNTY
    FROM cte 
    WHERE ID = c.ID
        AND TERM < c.TERM
        AND COUNTY IS NOT NULL
    ORDER BY TERM DESC) as p
OUTER APPLY (
    SELECT TOP 1 COUNTY
    FROM cte 
    WHERE ID = c.ID
        AND [SEQUENCE] = 1
    ORDER BY TERM DESC) as p1

答案 1 :(得分:0)

查看示例:

SELECT * into tbl_filltest FROM (
VALUES (1,Null),(2,Null),(3,5),(4,Null),(5,Null),(6,Null),(7,4),(8,Null),9,Null),(10,1)
 ) as t(c1,c2)
 GO
SELECT * FROM tbl_filltest
  GO
;WITH GoodValues as (SELECT * FROM tbl_filltest WHERE c2 is not null),
NullValues as (SELECT * FROM tbl_filltest WHERE c2 is null)
UPDATE n SET c2 = g1.c2 FROM GoodValues as g1
OUTER APPLY (SELECT MAX(c1) as Min_c1 FROM GoodValues as i WHERE g1.c1 > i.c1) as g2
INNER JOIN NullValues as n 
ON n.c1 > IsNull(g2.Min_c1,0) and n.c1 < g1.c1
GO
SELECT * FROM tbl_filltest
GO