更新ID匹配的数据和用例来选择哪些数据

时间:2015-03-12 16:27:10

标签: sql sql-server tsql sql-update

我有两张桌子

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

如何T1.Truck = T2.ResourceID T2.Type = R T1.Trailer = T2.ResourceID T2.Type = F T1.ID = T2.IDUPDATE 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 如何更新{{1}}。

这是我到目前为止所拥有的

{{1}}

这只会卡车,而不是预告片。

我错过了什么?

3 个答案:

答案 0 :(得分:1)

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

如果您执行了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

您可以看到TypeR匹配时,F的更新将更新为null等。

一种解决方案是加入T2表两次:

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

如果可能并非总是同时使用这两种类型(RF),请使用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

旁注:使用派生表的别名(也是表名)可能会非常混乱,应该避免使用。

答案 1 :(得分:0)

在更新PIVOT

之前,您可以t2t1

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

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

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

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

答案 2 :(得分:-1)

您可以针对每种情况使用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