2016-05-10 9 views
0

私はSOで検索しましたが、私の目的には何も見つかりませんでした。あるテーブルから別のテーブルにのみ一意の行を挿入する必要があります。私は:SQL Serverは複数の列にのみ基づいて新しい行を挿入します

TABLE1

id name bookid bookname start_date end_date rel_date rel_id 
1 horror 1221 rockys 04/01/2016 04/30/2016 05/01/2016 4545 
2 horror 1331 elm  04/01/2016 04/30/2016 05/01/2016 5656 

表2

id name bookid bookname start_date end_date rel_date rel_id 
1 horror 1221 rockys 04/01/2016 04/30/2016 05/01/2016 4545 
2 horror 1441 elm  04/01/2016 04/30/2016 05/01/2016 5656 

をIは表2にID = 2と行TABLE1に挿入する必要があり、また、ID = 2と行を削除します残りの列が一致してもbookidが異なるため、table1から取得します。

insert into table1 
select * from table2 
where not exists (select * from table2 where table1.id = table2.id 
and table1.name = table2.name and table1.bookid = table2.bookid and 
table1.bookname = table2.bookname and table1.start_date = table2.start_date 
and table1.end_date = table2.end_date and table1.rel_date =   table2.rel_date 
and table1.rel_id = table2.rel_id) 

私は1つのSQLブロック内にこのすべてを行うことができます任意の方法: 私は、次の試してみましたか?

+0

最初に削除して次に挿入するために結合を使用する – techspider

+0

ちょうどbookidに問題がある場合、なぜ結合で更新クエリを書くことができないのですか? – techspider

+2

また、TSQLの 'MERGE'コマンドを調べることもできます。 –

答えて

0

理論上、次のマージステートメントは、あなたが探しているものを達成するはずです。

MERGE table1 [Target] 
    USING table2 [Source] 
    ON ([Target].[name] = [Source].[name] 
      AND 
     [Target].[bookname] = [Source].[bookname] 
      AND 
     [Target].[start_date] = [Source].[start_date] 
      AND 
     [Target].[end_date] = [Source].[end_date] 
      AND 
     [Target].[rel_date] = [Source].[rel_date] 
      AND 
     [Target].[rel_id] = [Source].[rel_id] 
    ) 
    WHEN MATCHED AND ([Target].[bookid] <> [Source].[bookid]) THEN 
     UPDATE 
      SET [Target].[name]    = [Source].[name]  
       ,[Target].[bookid]   = [Source].[bookid]   
       ,[Target].[bookname]   = [Source].[bookname] 
       ,[Target].[start_date]  = [Source].[start_date]  
       ,[Target].[end_date]   = [Source].[end_date] 
       ,[Target].[rel_date]   = [Source].[rel_date] 
       ,[Target].[rel_id]   = [Source].[rel_id]   
    WHEN NOT MATCHED THEN 
    INSERT(   
      [name]   
      ,[bookid]  
      ,[bookname]  
      ,[start_date] 
      ,[end_date]  
      ,[rel_date]  
      ,[rel_id]  
     ) 
    VALUES 
    (  
      [Source].[name]    
      ,[Source].[bookid]  
      ,[Source].[bookname]   
      ,[Source].[start_date] 
      ,[Source].[end_date]   
      ,[Source].[rel_date]   
      ,[Source].[rel_id] 
    ); 

この方法にはいくつかのリスクと制限があります。 [id]列に一意制約がある場合は、それを識別列として設定する必要があります。それ以外の場合は、一意性違反エラーが発生します。また、table1の[id]列の値がtable2の[id]列と異なる場合、merge文はtable1の元の[id]値を保持します。

基本的にこのクエリは、table1の既存のレコードをtable2の一致するレコードで更新し、table2の新しいレコードをtable1に挿入します(存在しない場合)。

+0

これはssisパッケージのsqlタスクの中にあるので、私はID列を持っていない/できません--- ID列があればパッケージは動作しません。本質的に私が必要とするのは、列のANYが異なる場合に更新が行われることです。 start_dateが異なる場合にのみ挿入が行われます。したがって、start_dateが同じだが列のいずれかが異なる場合、それは更新です。 start_dateが異なる場合、残りの列の内容に関係なく、新しい行が挿入されます。 - Matt –

+0

私はもう少し情報が必要だと思う。更新が必要なレコードを一意に識別するために、どの列をキー入力しますか?それは[id]列ですか、そうであれば他の列の組み合わせですか? –

0

あなたはtable2からbookid値の更新についてだけ心配している場合は、あなたのid列はあなたがかもしれない2つのテーブル内で一意ではないと思う場合は、以下のクエリ

UPDATE t1 SET t1.bookid = t2.bookid 
FROM table1 t1 
JOIN table2 t2 ON t1.id = t2.id 

bookidの値を変更することができますJOINに他の一致する列を追加することを検討する必要があります。

+0

彼は "残りの列が一致する"と言っていたので、id列が一意ではない可能性があります。あなたの 'ON'節でもっと必要となるかもしれません。 –

+1

彼は実際にその例で何をしたいのかよく分かりません。しかし、とにかく、あなたのメモを追加しました。ありがとう – techspider

0

あなたがあなたの目的を達成するために必要があるのはすべて、このです:

DELETE T1 
FROM Table1 T1 
JOIN Table2 T2 
    ON T1.ID = T2.ID 
    AND T1.bookid <> T2.bookid 

INSERT INTO Table1 
SELECT id, name, bookid, bookname, start_date, end_date, rel_date, rel_id 
FROM Table2 T2 
LEFT OUTER JOIN Table1 T1 
    ON T1.ID = T2.ID 
    AND T1.bookid = T2.bookid 
WHERE T1.id IS NULL 

注意をあなたのIDフィールドがない場合はこと:それは頼まれたとおりの質問に答えるために、しかし

UPDATE T1 
SET T1.bookid = T2.bookid 
FROM Table1 T1 
JOIN Table2 T2 
    ON T1.ID = T2.ID 

他の条件をON句に追加する必要があります。

関連する問題