如何填充先前行的缺失值

时间:2014-04-30 06:05:08

标签: tsql missing-data

考虑这个表(测试):

C1  C2  Data
----------------
1   101 A1
1   104 A4
1   105 A5
2   101 B1
2   102 B2
2   103 B3
2   105 B5

和此表(OtherTable)

C2
---
100
101
102
103
104
105
106

我想要的是从上一个可用行和OtherTable填充上面缺少的行    - 即。 C1得到相同的值,C2来自OtherTable,Data得到相同的值。

C1  C2  Data
----------------
1   101 A1
1   102 A1   -- <<< Filled in from OtherTable & last available row 'A1'
1   103 A1   -- <<< Filled in from OtherTable & last available row 'A1'
1   104 A4
1   105 A5
2   101 B1
2   102 B2
2   103 B3
2   104 B3  -- <<< Filled in from OtherTable &  last available row 'B3'
2   105 B5

我已经建立了这个:

WITH Keys AS 
(
    SELECT 
        T.C1, 
        O.C2
    FROM
        TEST T
        CROSS APPLY (SELECT C2 FROM OtherTable) O 
    GROUP BY
        T.C1, 
        O.C2
),
MaxMin AS
(
    SELECT
        C1,
        MIN(C2) LowerBound,
        MAX(C2) UpperBound
    FROM
        Test 
    GROUP BY
        C1
)
SELECT
    K.C1, 
    K.C2,
    T.Data
FROM
    Keys K
    LEFT JOIN Test T 
        ON      
            T.C1 = K.C1 
            AND T.C2 = K.C2 
    INNER JOIN MaxMin M 
        ON
            K.C1 = M.C1 
            AND K.C2 BETWEEN M.LowerBound AND M.UpperBound

我到目前为止

C1  C2  Data
----------------
1   101 A1
1   102 NULL
1   103 NULL
1   104 A4
1   105 A5
2   101 B1
2   102 B2
2   103 B3
2   104 NULL
2   105 B5

但是我看不到如何应用数据列,而且我也觉得递归CTE是为了减少上面的查询,但我看不出如何。


(这是获取样本的TSQL)

IF EXISTS (SELECT 1 FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 'Test') 
    DROP TABLE Test;

CREATE TABLE Test (C1 INT, C2 INT, Data NVARCHAR(10));

INSERT INTO Test (C1, C2, Data) VALUES
(1, 101, 'A1'),
--(1, 102, 'A1'),
--(1, 103, 'A1'),
(1, 104, 'A4'),
(1, 105, 'A5'),
(2, 101, 'B1'),
(2, 102, 'B2'),
(2, 103, 'B3'),
--(2, 104, 'B3'),
(2, 105, 'B5');


IF EXISTS (SELECT 1 FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 'OtherTable') 
    DROP TABLE OtherTable;

CREATE TABLE OtherTable (C2 INT);

INSERT INTO OtherTable (C2) VALUES
(100),
(101),
(102),
(103),
(104),
(105),
(106);

1 个答案:

答案 0 :(得分:2)

从CTE中的测试中找出每C2的最小值和最大值C1(不一定是CTE),并使用OtherTable将其加入between。 使用Data

排序的top(1)获取C2 desc值相关子查询
with C as
(
  select C1, 
         min(C2) minC2,
         max(C2) maxC2
  from test
  group by C1
)
select C.C1,
       O.C2,
       (
       select top(1) T.Data
       from test as T
       where T.C1 = C.C1 and
             T.C2 <= O.C2
       order by T.C2 desc
       ) as Data
from C
  inner join OtherTable as O
    on O.C2 between C.minC2 and C.maxC2

SQL Fiddle