j'ai deux tables
T1: ID, Truck, Trailer 1 null null 2 null null T2: ID, Type, ResourceID 1 R 111 1 F 222 1 D 333 2 R 444 2 F 555
J'ai besoin d'un résultat où
ID, Truck, Trailer 1 111 222 2 444 555
Comment puis-je mettre à jour T1.Truck = T2.ResourceID
lorsque T2.Type = R
et T1.Trailer = T2.ResourceID
lorsque T2.Type = F
où T1.ID = T2.ID
C'est ce que j'ai jusqu'ici
UPDATE T1 SET T1.Truck = CASE WHEN T2.Type = 'R' THEN T2.ResourceId ELSE T1.Truck END, T1.Trailer = CASE WHEN T2.Type = 'F' THEN T2.ResourceId ELSE T1.Trailer END FROM T1 INNER JOIN (SELECT Id, Type, ResourceId FROM T2) T2 ON T1.Id = T2.Id
Ce sera seulement le camion, mais pas la bande-annonce.
Qu'est-ce que je rate?
Le problème avec votre requête de mise à jour actuelle est que la mise à jour mettra à jour une colonne à null car elle ne peut pas correspondre aux deux conditions en même time.
Si vous avez fait un select *
au lieu de la mise à jour, le résultat ressemblerait à ceci:
ID Truck Trailer Id Type ResourceId 1 NULL NULL 1 R 111 -- this will set R = 111 and F = null 1 NULL NULL 1 F 222 -- this will set F = 222 and R = null 1 NULL NULL 1 D 333 -- this will set R = null and F = null 2 NULL NULL 2 R 444 -- this will set R = 444 and F = null 2 NULL NULL 2 F 555 -- this will set R = null and F = 555
Ici, vous pouvez voir que lorsque Type
correspond à R
la mise à jour pour F
sera mise à jour à null
et cetera.
Une solution consiste à join la table T2
deux fois:
UPDATE T1 SET T1.Truck = T2.ResourceId , T1.Trailer = T3.ResourceId FROM T1 INNER JOIN (SELECT Id, ResourceId FROM T2 WHERE Type = 'R') T2 ON T1.Id = T2.Id INNER JOIN (SELECT Id, ResourceId FROM T2 WHERE Type = 'F') T3 ON T1.Id = T3.Id
S'il n'y a pas toujours les deux types ( R
, F
), utilisez la left join
au lieu de inner join
et vérifiez null
valeurs null
.
Edit: penser un peu plus donne cette requête:
UPDATE T1 SET T1.Truck = ISNULL(T.rValue, T1.Truck), T1.Trailer = ISNULL(T.fValue, T1.Trailer) FROM T1 INNER JOIN ( SELECT Id, rValue = MAX(CASE WHEN Type = 'R' THEN ResourceId END), fValue = MAX(CASE WHEN Type = 'F' THEN ResourceId END) FROM T2 GROUP BY id ) T ON T1.Id = T.Id
D'un autre côté: l'utilisation d'un alias pour une table dérivée qui est aussi un nom de table peut être assez déroutant et devrait être évité.
vous pouvez PIVOT
la table t2
avant de mettre à jour la table t1
Utilisez la requête suivante pour faire pivoter la table t2
.
SELECT ID, R, F FROM t2 PIVOT (Max(resourceID) FOR type IN ([R],[F]))pv
Maintenant, le résultat sera dans le format de la table t1
, vous pouvez facilement mettre à jour en utilisant la requête suivante
UPDATE A SET Trailer = F, Truck = R FROM t1 A INNER JOIN (SELECT ID, R, F FROM t2 PIVOT (Max(resourceID) FOR type IN ([R], [F]))pv) B ON A.ID = b.ID
SQLFIDDLE DEMO
Vous pouvez utiliser un JOIN
avec une condition pour chaque cas, donc vous JOIN
à T2
deux fois. D'abord sur l' Id
et [Type] = 'R'
et encore, avec [Type] = 'F'
.
Voici un exemple de code exécutable:
CREATE TABLE #t1 (id INT, Truck INT, Trailer int) CREATE TABLE #t2 (id INT, [Type] VARCHAR(1), ResourceId int) INSERT INTO #t1 ( id, Truck, Trailer ) VALUES (1, NULL, NULL), (2, NULL, NULL) INSERT INTO #t2 ( id, [Type], ResourceId ) VALUES ( 1, 'R', 111), ( 1, 'F', 222), ( 1, 'D', 333), ( 2, 'R', 444), ( 2, 'F', 555) UPDATE #t1 SET Truck = TR.ResourceId, Trailer = TF.ResourceId FROM #t1 INNER JOIN #t2 AS TR ON TR.id = #t1.id AND TR.[Type] = 'R' INNER JOIN #t2 AS TF ON TF.id = #t1.id AND TF.[Type] = 'F' SELECT * FROM #t1 DROP TABLE #t1 DROP TABLE #t2