Sql-Server
SQL 更新目標表中具有相同 id 但與源表不同值的多行
我有兩個不同的表,它們有一個名為 id 的公共列:
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
我需要編寫一個更新語句,該語句基本上將 id=1 的第一行的值放入 id=1 的值,將
Table2
idTable1
=1 的第二行的值Table2
放入Table1
id=1 的值,這樣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
有沒有辦法讓 udpate
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 語句中做到這一點?我不想最好使用游標。
兩個表中還有其他列,並非所有
id
值Table1
都存在,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');
請記住,我們還沒有提供任何方法來確定 Table1 和 Table2 對於給定的 id 值匹配哪些行,我將讓 row_number() 生成一個“匹配”rowid。
然後我們將利用 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。