3

次のような SQL テーブルがあります。

ID, Date,   D1, D2, D3
1   1/1/13  0   X   A
2   1/2/13          
3   1/3/13  1
4   1/4/13          B
5   1/5/13  

次のように更新する必要があります。

ID, Date,   D1, D2, D3
1   1/1/13  0   X   A
2   1/2/13  0   X   A       
3   1/3/13  1   X   A   
4   1/4/13  1   X   B
5   1/5/13  1   X   B

基本的に、すべてのヌルをその前の値で埋めます。これは一度だけ実行されます。ループは最良の選択肢でしょうか? それとももっと効果的なものはありますか?

4

2 に答える 2

1

列を使用して順序を決定すると仮定するとID、ループなしで実行できます。

あなたがこれをしたいかどうかは別の問題です - それはきれいに見えません:

declare @t table (ID int, Date date,   D1 int, D2 char(1), D3 char(1))
insert into @t(ID, Date,   D1, D2, D3) values
(1,'20130101',0,'X','A'),
(2,'20130201',null,null,null),     
(3,'20130301',1,null,null),
(4,'20130401',null,null,'B'),
(5,'20130501',null,null,null)

update a
set
    a.D1 = COALESCE(a.D1,d1.D1),
    a.D2 = COALESCE(a.D2,d2.D2),
    a.D3 = COALESCE(a.D3,d3.D3)
from
    @t a
        left join
    @t D1
        on
            D1.ID < a.ID and
            D1.D1 IS NOT NULL
        left join
    @t D1_anti
        on
            D1_anti.ID < a.ID and
            D1_anti.D1 is not null and
            D1_anti.ID > D1.ID
        left join
    @t D2
        on
            D2.ID < a.ID and
            D2.D2 IS NOT NULL
        left join
    @t D2_anti
        on
            D2_anti.ID < a.ID and
            D2_anti.D2 is not null and
            D2_anti.ID > D2.ID
        left join
    @t D3
        on
            D3.ID < a.ID and
            D3.D3 IS NOT NULL
        left join
    @t D3_anti
        on
            D3_anti.ID < a.ID and
            D3_anti.D3 is not null and
            D3_anti.ID > D3.ID
where
    D1_anti.ID is null and
    D2_anti.ID is null and
    D3_anti.ID is null

select * from @t

基本的に、結合を実行して適用可能な前の行を見つけようとし、_anti結合を実行して、前に見つかった各行が存在する最新の行であることを確認します。

于 2013-05-15T14:02:58.063 に答える