Mettre à jour datatables où l'ID correspond et cas d'utilisation pour choisir queldatatables

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 = FT1.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