更新 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 = F
和 T1.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
您可以为每个案例使用一个带有条件的 JOIN
,因此您需要 JOIN
到 T2
两次。首先是 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
我有两张桌子
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 = F
和 T1.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
您可以为每个案例使用一个带有条件的 JOIN
,因此您需要 JOIN
到 T2
两次。首先是 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