更新 ID 匹配的数据和用例以选择什么数据

Update data where ID match and use case to choose what data

我有两张桌子

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

我需要一个结果

ID, Truck, Trailer
1   111    222
2   444    555

如何在 T2.Type = R 时更新 T1.Truck = T2.ResourceID 以及在 T2.Type = FT1.ID = T2.ID 时更新 T1.Trailer = T2.ResourceID

这是我目前所拥有的

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

这只会是卡车,不会是拖车。

我错过了什么?

您当前更新查询的问题是更新会将一列更新为空,因为它无法同时匹配两个条件。

如果您执行 select * 而不是更新,结果将如下所示:

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

在这里您可以看到,当 Type 匹配 R 时,F 的更新将更新为 null 等等。

一个解决方案是加入 T2 table 两次:

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

如果可能不总是存在两种类型 (R,F),则使用 left join 而不是 inner join 并检查 null 值。

编辑:再考虑一下给出了这个查询:

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

附带说明:为派生的 table 使用别名,这也是一个 table 名称可能会造成混淆,应该避免。

您可以在更新 t1 table

之前 PIVOT table t2

使用以下查询来透视 t2 table。

SELECT ID, R, F
FROM   t2
    PIVOT (Max(resourceID)
           FOR type IN ([R],[F]))pv

现在结果将采用 t1 table 的格式,您可以使用以下查询轻松更新

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

您可以为每个案例使用一个带有条件的 JOIN,因此您需要 JOINT2 两次。首先是 Id[Type] = 'R',然后是 [Type] = 'F'.

下面是一些可运行的示例代码:

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