1

IDで結合して、最初のテーブルを2番目の値で更新する必要があるt-sql演習を解決しようとしています。参加できない場合は、デフォルト ID の値を使用します (デフォルト ID は null の ID です)

実行して確認してください

declare @t as table (
    [id] INT
    ,val int
)

insert into @t values (null, null)
insert into @t values (2, null)
insert into @t values (3, null)
insert into @t values (4, null)

declare @t2 as table (
    [id] INT
    ,val int
)

insert into @t2 values (null, 11)
insert into @t2 values (2, 22)
insert into @t2 values (3, 33)


select * from @t
select * from @t2

update t
set t.val = t2.val
from @t as t join @t2 as t2
    on t.id = t2.id
        or 
        (
            (t.id is null or t.id not in (select id from @t2))
            and t2.id is null
        )




select * from @t

ここに結果があります

--@t
id      val
---------------
NULL    NULL
2       NULL
3       NULL
4       NULL

--@t2
id      val
---------------
NULL    11
2       22
3       33

--@t after update
id      val
---------------
NULL    11
2       22
3       33
4       NULL

最後の行の val を 11 にする方法は?

4       11
4

3 に答える 3

3

このソリューションは、t2 への結合を 2 回残してから、合体を行います。

2 番目のON結合では、結合に失敗したレコードに一致し、「デフォルト」のケースを探します。

UPDATE t
set t.val = COALESCE(t2.val,t3.val)
from @t as t 
    LEFT join @t2 as t2
    on t.id = t2.id
    LEFT JOIN @t2 t3 
    ON t2.id is null and t3.id is null

ここで動作するのを見てください

于 2012-04-16T21:32:47.773 に答える
2

更新のためにこれを試してください...

update t
set t.val = t2.val
from @t as t join @t2 as t2
    on t.id = t2.id
        or 
        (
            (t.id is null or not exists (select * from @t2 where id = t.id))
            and t2.id is null
        )

問題はnot in演算子とnull値にあります。これもうまくいくでしょう...

update t
set t.val = t2.val
from @t as t join @t2 as t2
    on t.id = t2.id
        or 
        (
            (t.id is null or t.id not in (select id from @t2 where id is not null))
            and t2.id is null
        )
于 2012-04-16T21:33:56.503 に答える
1

ここで役立つかもしれないテクニックがあります。

書きたい単純なコードから始めます。

MERGE INTO @t AS target 
   USING source 
      ON target.id = source.id 
WHEN MATCHED THEN
   UPDATE 
      SET val = source.val;

source次に、要件を満たす表式 ( ) を記述します。

要件1:「IDによる参加」

-- 単純な存在量化など

SELECT id, val
  FROM @t2 AS T2
 WHERE id IN ( SELECT id FROM @t ) 

要件 2: 「参加できない場合は、デフォルト ID の値を使用します (デフォルト ID は null の ID です)」

-- 最初idに、ソースに存在しないターゲットの値を見つけます。

SELECT id
  FROM @t
EXCEPT
SELECT id
  FROM @t2

次に、Id が null であるソースからの行と結果をクロス結合します。

SELECT DT1.id, T2.val
  FROM ( SELECT id
          FROM @t
         EXCEPT
         SELECT id
          FROM @t2 ) AS DT1, 
       @t2 AS T2 
 WHERE T2.id IS NULL

この時点で、いくつかのテスト データをクエリして、各クエリがそれぞれの要件を満たしていることを確認します。

上記の 2 つの結果を結合して、1 つのテーブル式を形成します。

SELECT id, val
  FROM @t2 AS T2
 WHERE id IN ( SELECT id
                 FROM @t )             
UNION
SELECT DT1.id, T2.val
  FROM ( SELECT id
          FROM @t
         EXCEPT
         SELECT id
          FROM @t2 ) AS DT1, 
       @t2 AS T2 
 WHERE T2.id IS NULL

次に、テーブル式をMERGEボイラープレート コードに挿入します。

WITH source
     AS
     (
      SELECT id, val
        FROM @t2 AS T2
       WHERE id IN ( SELECT id
                       FROM @t )             
      UNION
      SELECT DT1.id, T2.val
        FROM ( SELECT id
                FROM @t
               EXCEPT
               SELECT id
                FROM @t2 ) AS DT1, 
             @t2 AS T2 
       WHERE T2.id IS NULL
     )
MERGE INTO @t AS target 
   USING source 
      ON target.id = source.id 
WHEN MATCHED THEN
   UPDATE 
      SET val = source.val;
于 2012-04-17T12:23:40.490 に答える