sql - 是否可以使用单个 UPDATE SQL 语句执行多个更新?

标签 sql sql-server sql-server-2005 tsql optimization

假设我有一个表 tbl,其中包含 idtitle 列。 我需要更改标题列的所有值:

  1. 从“a-1”到“a1”,
  2. 从“a.1”到“a1”,
  3. 从“b-1”到“b1”,
  4. 从“b.1”到“b1”。

现在,我正在执行两个 UPDATE 语句:

UPDATE tbl SET title='a1' WHERE title IN ('a-1', 'a.1')
UPDATE tbl SET title='b1' WHERE title IN ('b-1', 'b.1')

如果表很小,并且单个语句在不到一秒的时间内完成,并且您只需要执行几条语句,那么这根本不是问题。

您可能客串了它 - 我有一个巨大的表需要处理(一条语句在大约 90 秒内完成),并且我有大量的更新需要执行。

那么,是否可以合并更新,以便只扫描表一次?或者,也许有更好的方法来处理这种情况。

编辑:请注意,我正在使用的真实数据以及我必须执行的数据更改并不是那么简单 - 字符串更长并且它们不遵循任何模式(它是用户数据,所以不能做出任何假设 - 它可以是任何东西)。

最佳答案

在更一般的情况下,每个新值可能有数百个映射,您将创建一个单独的旧值和新值表,然后在 UPDATE 语句中使用该表。在 SQL 的一种方言中:

CREATE TEMP TABLE mapper (old_val CHAR(5) NOT NULL, new_val CHAR(5) NOT NULL);
...multiple inserts into mapper...
INSERT INTO mapper(old_val, new_val) VALUES('a.1', 'a1');
INSERT INTO mapper(old_val, new_val) VALUES('a-1', 'a1');
INSERT INTO mapper(old_val, new_val) VALUES('b.1', 'b1');
INSERT INTO mapper(old_val, new_val) VALUES('b-1', 'b1');
...etcetera...

UPDATE tbl
   SET title = (SELECT new_val FROM mapper WHERE old_val = tbl.title)
   WHERE title IN (SELECT old_val FROM mapper);

这两个 select 语句都至关重要。第一个是相关子查询(不一定很快,但如果映射器表有数千行,则比大多数替代查询更快),它从映射表中提取与旧值对应的新值。第二个确保只修改那些在映射表中具有值的行;这很重要,否则,对于没有映射条目的那些行,标题将设置为 null(这些是在开始之前正常的记录)。

对于一些替代方案,CASE 操作是可以的。但是,如果您要执行数百、数千或数百万个映射,那么您可能会超出 DBMS 中 SQL 语句长度的限制。

关于sql - 是否可以使用单个 UPDATE SQL 语句执行多个更新?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/412101/

相关文章:

sql - 比较同一个表中的值集

sql-server - SQL登录已经存在的错误

sql-server-2005 - SQL Server 2005 查询

sql - 如何正确检查SQL Server 2005中是否存在临时表?

MySQL 重复插入

java - 使用哪个连接操作将多个表与 JPA/SQL 查询组合起来?

mysql - 计算列的 SQL View

java - 如何为 linux (fedora) 安装 Microsoft SQL Server?

sql-server - SQL Server 距离搜索

sql-server - 我需要在 sql server 上使用生成脚本来备份 View 和过程