在SQL中更新具有不同值的多个行

Bob*_*Bob 7 sql sql-update

我有这样一张桌子:

SKU            Size
A              10
B              10
C              10
D              10
E              10
F              10
G              10
Run Code Online (Sandbox Code Playgroud)

我想将其更改为:

SKU            Size
A              20
B              10
C              30
D              10
E              80
F              10
G              60
Run Code Online (Sandbox Code Playgroud)

我有超过3000行记录要更新.如何使用SQL更新命令执行此操作?

Dam*_*ver 18

UPDATE T
SET Size = CASE SKU
    WHEN 'A' THEN 20
    WHEN 'B' THEN 10
    WHEN 'C' THEN 30
    WHEN ...
END
Run Code Online (Sandbox Code Playgroud)

或者可能有一个计算大小的公式,但你没有在你的问题中给出它(或者我们可能不得不切换到更复杂的CASE表达式,但同样,问题中的细节太少).

  • 我使用上面的查询,并将主键作为“WHEN”条件。对于大型表(约 4M 条记录),如果添加“WHERE id in (...)”子句,查询速度会更快。 (2认同)

Jon*_*ler 5

创建一个表,将 SKU 映射到新的大小;从中更新主表。

许多 SQL 方言都有通过连接表进行更新的符号。有些没有。这将在没有这样的符号的情况下工作:

CREATE TABLE SKU_Size_Map
(
     SKU     CHAR(16) NOT NULL,
     Size    INTEGER NOT NULL
);
...Populate this table with the SKU values to be set...
...You must have such a list...

UPDATE MasterTable
   SET Size = (SELECT Size FROM SKU_Size_Map
                WHERE MasterTable.SKU = SKU_Size_Map.Size)
 WHERE SKU IN (SELECT SKU FROM SKU_Size_Map);
Run Code Online (Sandbox Code Playgroud)

主要的 WHERE 条件需要避免在没有匹配行的情况下将大小设置为 null。

您可能也可以使用 MERGE 语句来做到这一点。但是对于这些符号中的任何一个的关键见解是您需要一个表来进行 SKU 和大小之间的映射。您要么需要表格,要么需要算法,而样本数据并未建议算法。


Pra*_*ana 0

使用OpenXML解决您的问题

例子

declare @i int

exec sp_xml_preparedocument @i output, 
'<mydata>
  <test xmlID="3" xmlData="blah blah blah"/>
  <test xmlID="1" xmlData="blah"/>
</mydata>'

insert into test 
select xmlID, xmlData 
from OpenXml(@i, 'mydata/test')
with (xmlID int, xmlData nvarchar(30))
where xmlID not in (select xmlID from test)

update test
set test.xmlData = ox.xmlData
from OpenXml(@i, 'mydata/test')
with (xmlID int, xmlData nvarchar(30)) ox
where test.xmlID = ox.xmlID

exec sp_xml_removedocument @i
Run Code Online (Sandbox Code Playgroud)