使用相同的 table 和多个变量和 WHERE IN 子句合并 SQL UPDATE 语句

Consolidating an SQL UPDATE statement using same table and multiple variables and WHERE IN clause

我有一个 table table1,我正在尝试将一列 completed 更新为基于 id 的特定值。因为 table 以及更新的列和 WHERE 子句字段保持不变,所以我一直在研究合并 SQL 语句的可能性。

我有一个 table1 这样的:

| id | completed |
| -- | --------- |
| 1  | NULL      |
| 2  | NULL      |
| 3  | NULL      |
| 4  | NULL      |
| 5  | NULL      |
| 6  | NULL      |
| 7  | NULL      |
| 8  | NULL      |
| 9  | NULL      |
| 10 | NULL      |
| 11 | NULL      |
| 12 | NULL      |

这是我目前的标准示例:(它继续另外 13 UPDATE 语句)

UPDATE table1 SET completed = 25
WHERE id IN (1, 2, 3, 4);

UPDATE table1 SET completed = 27
WHERE id IN (5, 6, 7, 8);

UPDATE table1 SET completed = 28
WHERE id IN (9, 10, 11, 12);

我试过类似的方法:(虽然我知道这是不对的)

UPDATE table1 (
     SET completed = 25 WHERE id IN (1, 2, 3, 4),
     SET completed = 27 WHERE id IN (5, 6, 7, 8),
     SET completed = 28 WHERE id IN (9, 10, 11, 12)
);

假设:id 在真实 table 中是无序的;跳过并且与完成的号码顺序无关

table1 的预期结果:

| id | completed |
| -- | --------- |
| 1  | 25        |
| 2  | 25        |
| 3  | 25        |
| 4  | 25        |
| 5  | 26        |
| 6  | 26        |
| 7  | 26        |
| 8  | 26        |
| 9  | 27        |
| 10 | 27        |
| 11 | 27        |
| 12 | 27        |

问题:鉴于上述情况,是否会有更统一的版本?还是第一个代码效率最高?

我也查看了 Whosebug 和文档,但没有看到直接解决的类似问题。

UPDATE table1 
 SET completed = CASE WHEN id IN (1, 2, 3, 4) THEN 25
                      WHEN id IN (5, 6, 7, 8) THEN 27
                      WHEN id IN (9, 10, 11, 12) THEN 28
                      ELSE completed END

更新 table 中的每一行,即使可能会将其中的大部分设置回原始值。

我也看到了这个:

id is unordered in the real table; skips and does not correlate to completed number order

鉴于此,您可能想要实际 创建一个 table(名称类似于 CompletionMap)来跟踪这些映射。像这样:

id status
1 25
2 25
3 25
4 25
5 27
6 27
7 27
8 27
9 28
10 28
11 28
12 28

此时,您甚至不再真的需要更新原始数据 table,因为您已经在数据库中拥有这些数据。但如果你真的想要,它看起来像这样:

UPDATE t1
 SET t1.completed = m.status
FROM t1
INNER JOIN CompletionMap m on m.id = t1.ID

如果您不想这样做,您也可以以类似的方式使用 Table-Value Constructor

UPDATE t1
 SET t1.completed = map.status
FROM t1
INNER JOIN (VALUES
    (1, 25),
    (2, 25),
    (3, 25),
    (4, 25),
    (5, 27),
    (6, 27),
    (7, 27),
    (8, 27),
    (9, 28),
    (10, 28),
    (11, 28),
    (12, 28)
 ) as map(id, status) on map.id = t1.ID

这具有额外的优势,可以更好地定位更新以仅影响所需的行。