交叉应用以使用多列填充值

时间:2014-11-04 15:33:19

标签: sql sql-server-2008

我有一个包含几列的表格。我想填充值以替换空值,但是这会因其他列而变得复杂。以下是我的样本:

date    id1   id2   id3   id4    value
1/1/14   a     1     1     1       1.2
1/2/14   a     1     1     1       NULL
1/8/14   a     1     1     1       2.3
1/1/14   a     2     1     1       10.1
1/2/14   a     2     1     1       12.3
1/17/14  a     2     1     1       NULL
1/18/14  a     2     1     1       10.8
1/1/14   a     2     3     1       100.3
1/2/14   a     2     3     1       NULL
1/6/14   a     2     3     1       110.4

我想复制value,而值仍然在id1-4的“组”内。例如,就要复制的值而言,所有“A-1-1-1”应与“a-2-1-1”隔离。我需要的输出是:

date    id1   id2   id3   id4    value
1/1/14   a     1     1     1       1.2
1/2/14   a     1     1     1       1.2
1/8/14   a     1     1     1       2.3
1/1/14   a     2     1     1       10.1
1/2/14   a     2     1     1       12.3
1/17/14  a     2     1     1       12.3
1/18/14  a     2     1     1       10.8
1/1/14   a     2     3     1       100.3
1/2/14   a     2     3     1       100.3
1/6/14   a     2     3     1       110.4

我可以使用CROSS APPLY为单个列执行此操作,但多列的语法让我感到困惑。生成临时数据的SQL是:

DECLARE @test TABLE
    (
    date DATETIME
    ,id1 VARCHAR(1)
    ,id2 INT
    ,id3 INT
    ,id4 INT
    ,value FLOAT
    )

    INSERT INTO @test VALUES
    ('2014-01-01','a','1','1','1','1.2')
    ,('2014-01-02','a','1','1','1',NULL)
    ,('2014-01-08','a','1','1','1','2.3')
    ,('2014-01-01','a','2','1','1','10.1')
    ,('2014-01-02','a','2','1','1','12.3')
    ,('2014-01-17','a','2','1','1',NULL)
    ,('2014-01-18','a','2','1','1','10.8')
    ,('2014-01-01','a','2','3','1','100.3')
    ,('2014-01-02','a','2','3','1',NULL)
    ,('2014-01-06','a','2','3','1','110.4')
    ;

    SELECT * FROM @test;

1 个答案:

答案 0 :(得分:2)

您可以使用apply

select t.*, coalesce(t.value, tprev.value) as value
from @test t outer apply
     (select top 1 value
      from @test t2
      where t2.id1 = t.id1 and t2.id2 = t.id2 and t2.id3 = t.id3 and t2.id4 = t.id4 and
            t2.date < t.date and t2.value is not null
      order by t2.date desc
     ) tprev;