J'ai deux tables différentes avec une colonne commune appelée 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
J'ai besoin d'écrire une déclaration de mise à jour qui mettra essentiellement la valeur de la première ligne avec id = 1 de Table2
en Table1
avec un id = 1 et la deuxième ligne avec id = 1 de Table2
en Table1
avec un id = 1 pour que Table1
ressemble maintenant à ceci
Table1
---- -------
id | Date
---- -------
1 2013-01-29 08:50:00.000
1 2013-01-29 15:28:00.000
Actuellement, cette instruction SQL
UPDATE Table1
SET Table1.date = T2.date
FROM
Table2 T2
INNER JOIN Table1 T1
ON T1.date = T2.date
est en train de faire Table1
ressemble à ceci, où il applique la première date qu'il trouve pour cet identifiant à toutes les lignes avec des identifiants correspondants dans la table de destination
Table2
---- -------
id | Date
---- -------
1 2013-01-29 08:50:00.000
1 2013-01-29 08:50:00.000
Existe-t-il un moyen de mettre à jour Table1
pour ressembler à ceci ci-dessous:
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
Existe-t-il un moyen de le faire dans une instruction SQL? Je ne veux pas utiliser de préférence un curseur.
Il y a d'autres colonnes dans les deux tables et pas toutes les valeurs de id
dans Table1
pourrait être présent dans Table2
et vice versa. Ces autres lignes et colonnes que je ne veux ni toucher ni modifier.
Impossible de trouver un moteur de violon SQL Server 2008, j'ai donc dû opter pour un serveur SQL Server 2014 ... donc je ne sais pas si les éléments suivants fonctionneront dans SQL Server 2008, mais fwiw ...
Configurez quelques exemples de données:
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');
En gardant à l'esprit que nous n'avons pas (encore) fourni de moyen pour déterminer les lignes à faire correspondre entre Table1 et Table2 pour une valeur d'ID donnée, je laisserai simplement row_number () générer un ID de ligne `` correspondant ''.
Et puis nous utiliserons la capacité de SQL Server à mettre à jour Table1 via une définition de table dérivée:
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;
Et les résultats:
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
Et voici un SQL Fiddle pour ce qui précède.
Vous avez déclaré que l'ordre des correspondances est important, mais il semble que vous n'ayez rien à ORDER BY dans le tableau 1 pour créer un ordre garanti pour correspondre à l'autre table et il n'y a aucun moyen dans SQL Server de classer les lignes après la date d'insertion , car les informations à ce sujet ne sont pas stockées. Dans cet esprit, il n'est pas possible de faire une correspondance avec le résultat souhaité. Il existe une solution pour mettre à jour les lignes avec une correspondance arbitraire dans chaque identifiant. Si cela pouvait suffire.
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
Cette solution correspondra à toutes les lignes individuellement mais ne peut garantir la commande.