Idという共通の列を持つ2つの異なるテーブルがあります。
Table1
---- -------
id | Date
---- -------
1 null
1 null
2 null
2 null
2 null
2 null
3 null
4 null
4 null
Table2
---- -------
id | Date
---- -------
1 2013-01-29 08:50:00.000
1 2013-01-29 15:28:00.000
2 2013-01-31 11:56:00.000
2 2013-03-11 16:08:00.000
2 2013-01-31 14:04:00.000
2 2013-01-31 14:08:00.000
3 2013-02-28 23:44:00.000
4 2013-01-31 14:04:00.000
4 2013-01-31 14:08:00.000
基本的に、Table2
のid = 1の最初の行の値をid = 1のTable1
に入れ、Table2
のid = 1の2番目の行の値をid = 1のTable1
に入れて、Table1
にする今のように見えます
Table1
---- -------
id | Date
---- -------
1 2013-01-29 08:50:00.000
1 2013-01-29 15:28:00.000
現在、このSQLステートメント
UPDATE Table1
SET Table1.date = T2.date
FROM
Table2 T2
INNER JOIN Table1 T1
ON T1.date = T2.date
Table1
を次のようにして、そのIDで最初に見つかった日付を、宛先テーブルのIDが一致するすべての行に適用します
Table2
---- -------
id | Date
---- -------
1 2013-01-29 08:50:00.000
1 2013-01-29 08:50:00.000
Table1
を以下のように更新する方法はありますか?
Table1
---- -------
id | Date
---- -------
1 2013-01-29 08:50:00.000
1 2013-01-29 15:28:00.000
2 2013-01-31 11:56:00.000
2 2013-03-11 16:08:00.000
2 2013-01-31 14:04:00.000
2 2013-01-31 14:08:00.000
3 2013-02-28 23:44:00.000
4 2013-01-31 14:04:00.000
4 2013-01-31 14:08:00.000
SQLステートメントでこれを行う方法はありますか?できればカーソルを使いたくない。
両方のテーブルに他の列があり、Table1
のすべてのid
値がTable2
にあるとは限りません。逆も同様です。触れたり変更したりしたくない他の行と列。
SQL Server 2008のフィドルエンジンが見つからなかったため、SQL Server 2014を選択する必要がありました。そのため、以下がSQL Server 2008で機能するかどうかはわかりませんが、fwiw ...
いくつかのサンプルデータをセットアップします。
create table Table1(id int, Date datetime null);
create table Table2(id int, Date datetime);
insert Table1 values (1,null)
insert Table1 values (1,null)
insert Table1 values (2,null)
insert Table1 values (2,null)
insert Table1 values (2,null);
insert Table2 values (1,'2013-01-29 08:50:00.000')
insert Table2 values (1,'2013-01-29 15:28:00.000')
insert Table2 values (2,'2013-01-31 11:56:00.000')
insert Table2 values (2,'2013-03-11 16:08:00.000')
insert Table2 values (2,'2013-01-31 14:04:00.000');
与えられたid値に対してTable1とTable2の間でどの行を一致させるかを決定する手段が(まだ)提供されていないことに留意して、row_number()に「一致する」行IDを生成させます。
次に、SQL Serverの機能を利用して、派生テーブル定義を介してTable1を更新します。
update T1
set T1.Date=T2.Date
from (select row_number() over(partition by id order by Date) as rowid,
id,
Date
from Table1
where Date is NULL) T1
join (select row_number() over(partition by id order by Date) as rowid,
id,
Date
from Table2) T2
on T1.id = T2.id
and T1.rowid = T2.rowid;
そして結果:
select * from Table1;
id Date
--- --------------------
1 2013-01-29T08:50:00Z
1 2013-01-29T15:28:00Z
2 2013-01-31T11:56:00Z
2 2013-01-31T14:04:00Z
2 2013-03-11T16:08:00Z
そして、これが上記の SQL Fiddle です。
一致の順序が重要であると述べましたが、他のテーブルと一致する保証された順序を作成するために、テーブル1のORDER BYに何もないようで、SQL Serverには挿入日後に行を順序付ける方法がありません。 、それに関する情報は保存されないため。これを念頭に置いて、希望する結果と照合することはできません。各ID内の任意の一致で行を更新するソリューションがあります。それで十分なら。
UPDATE t
SET t.[date] = tt.[date]
FROM (SELECT *,
Row_number()
OVER (
partition BY id
ORDER BY [date]) AS rno
FROM Table1) AS t
INNER JOIN (SELECT *,
Row_number()
OVER (
partition BY id
ORDER BY [date]) AS rno
FROM Table2) AS tt
ON t.id = tt.id
AND t.rno = tt.rno
このソリューションはすべての行を個別に照合しますが、順序を保証することはできません。