SQL - 将值更新到编号列中
我有一组查询用于根据其序列号更新来自另一个表(cards
)的代码的表(boxes
)。序号为1的卡进入boxes
表中名为code_1
的列,以此类推,以获得有限数量的可能序列号。因为它是有限的,我可以这样做:SQL - 将值更新到编号列中
update b
set code_1 = c.codes
from boxes as b inner join cards as c
on b.service_id = c.service_id and c.sequence_number = 1;
update b
set code_2 = c.codes
from boxes as b inner join cards as c
on b.service_id = c.service_id and c.sequence_number = 2;
update b
set code_3 = c.codes
from boxes as b inner join cards as c
on b.service_id = c.service_id and c.sequence_number = 3;
...
update b
set code_n = c.codes
from boxes as b inner join cards as c
on b.service_id = c.service_id and c.sequence_number = n;
但我的问题是:是否有编写一个查询,将适当的基于源的序列号更新所有列的方式吗?
你可以用下面的代码
UPDATE b
SET code_1 = CASE sequence_number
WHEN 1 THEN 3
WHEN 2 THEN 4
WHEN 3 THEN 5
END,
code_2 = CASE sequence_number
WHEN 1 THEN 'New Title 1'
WHEN 2 THEN 'New Title 2'
WHEN 3 THEN 'New Title 3'
END
WHERE sequence_number IN (1,2)
做到这一点,据我所知,就可以实现从这种多多次更新。希望这可以帮助你。
update b set code_1 = (select c.codes from cards as c on b.service_id = i.service_id and c.sequence_number = 1),
code_2= (select c.codes from cards as c on b.service_id = i.service_id and c.sequence_number = 2),
code_3= (select c.codes from cards as c on b.service_id = i.service_id and c.sequence_number = 3),
.
.
.
code_n= (select c.codes from cards as c on b.service_id = i.service_id and c.sequence_number = n);
嗯......如果你不想硬编码它,也许你可以使用循环代替方法。我不是超强的SP的,但这样的事情:
DECLARE @LoopCounter INT = 1, @codeNumber int;
WHILE (SELECT boxID FROM boxes)< (select max(boxID) as boxIDMax from boxes)
BEGIN
SET @codeNumber= <get_your_codeID_here_with_select_where_boxID=codeID>
update b
set @codeNumber = c.codes
from boxes as b inner join cards as c
on b.service_id = i.service_id and c.sequence_number = boxID;
SET @LoopCounter = @LoopCounter + 1;
END
这不起作用,因为您不能使用变量('@ codeNumber')来指定正在更新的列。使用循环来创建并执行动态SQL语句 - 但这仍然是几个查询。 –
您可以通过使用PIVOT
;WITH T AS (
select * from
(select * from cards) src
pivot (MAX(codes) for sequence_number IN ([1],[2],[3],...,[n])) pvt
)
update b
SET
code_1 = T.[1],
code_2 = T.[2],
code_3 = T.[3],
....,
code_n = T.[n]
from
boxes b
inner join T ON b.service_id = T.service_id
将要更新的列的数量在设计时是不知道的事实使它意味着严格来说,这不能在单个查询中完成。您需要构建然后执行动态SQL查询来执行此操作。
@Troels答案是一种方法来处理N上的这个循环,并为每个迭代问题和更新。这会比现在更方便的代码,可能是你真正想要的,但不是一个单一的查询。通过建立从一箱的连接到卡
- 动态生成查询,用N“项”
- 开始:
为了让你不得不单查询作为pivot语句中的子查询,为每个Item生成一个列(这是动态SQL是强制性的)
- 使主要查询成为CTE的第一部分
- 接下来,将框连接到CTE tableset上service_id为
- 使它成为一个更新语句,用N(动态生成的)设置子句中的项目,设置为从枢轴集中适当的列中的值(和一定要检查并妥善处理空值)
这将是一个痛苦的写作和轻微的头痛随着时间的推移进行修改。除非有很强的理由(需要成为一个单独的事务),否则我会从@Troels版本开始,并添加动态SQL。
如果当然,不得不说的是,最好的办法是规范表boxes
,以便它不包含未知的行数,说,Boxes
(主键box_id
)和BoxContents(主键box_id, sequence_number
)
...当我写这篇文章时,@ sarslan的主要答案就出现了,正是我所说的。如果你知道N,它就可以工作,但如果你不知道,必须建立并运行。
'n'是已知的固定值,还是可以变化? –
@PhilipKelley'n'因给定的'service_id'而有所不同,但确实有一个最大值,所以如果需要的话我可以硬编码。 – Michael
另外,你使用的是什么RDBMS? –