【问题标题】:how to update row with data from another and already updated row in the same update command SQL Server如何在同一更新命令 SQL Server 中使用来自另一个已更新行的数据更新行
【发布时间】:2015-03-25 20:44:49
【问题描述】:

我必须使用我已经在前一行中更新的值来更新一行。写的很奇怪,所以我举个例子:

create table #temp (col1 int, col2 int)

insert into #temp values(1, 2)
insert into #temp values(2, 4)
insert into #temp values(3, 6)

update T set 
col2 = case when col1 = 1 then 3 else (select col2 from #temp where col1 = 1) * col2 end 
from #temp T

我得到的结果是:

col1        col2
----------- -----------
1           3
2           8
3           12

而我需要的是:

col1        col2
----------- -----------
1           3
2           12
3           18

在这种情况下有类似 NEW.value 的东西吗?

PS:我知道这个例子中的值是静态的,但在我的实际代码中它们不是。假设第一条记录中col2的值是未知的

【问题讨论】:

  • 如果您对第一行 3 的值进行硬编码,那么为什么不将 col2*3 用于其他行?
  • 那是因为这个例子看起来不像实际的过程。实际代码不会使用任何静态值
  • 那么它应该如何获得第一个值呢?因为你应该将它存储到一个变量中并在UPDATE中使用它。
  • 所有行同时更新。没有顺序。 “我已经在前一行更新的值”的概念没有任何意义。
  • 想象我有 2 个表,我在第一行更新它们(通过连接),但在第二个中我需要使用第二个表的更新值来获取正确的结果

标签: sql sql-server tsql sql-update


【解决方案1】:

你是说你想要这样的东西吗?

create table #temp (col1 int, col2 int)

insert into #temp values(1, 2)
insert into #temp values(2, 4)
insert into #temp values(3, 6)

DECLARE @cvalue int;
select @cvalue = 3;

update T set 
col2 = case when col1 = 1 then @cvalue else @cvalue * col2 end 
from #temp T

SELECT * FROM #temp

基本上,您首先获得想要在整个更新过程中保持不变的值并将其放入变量中,然后在更新中使用该变量。

请注意,无法计算分配给一列的值,然后在同一更新语句中的其他计算中使用该列的值。这将违反 SQL 的设计工作方式(如果该 DID 工作,它会破坏大量其他查询和更新)。这被称为“万圣节问题”,您可以在此处阅读有关它的信息,以及 SQL Server 如何故意避免您在此处似乎想要的“级联更新”问题: http://sqlperformance.com/2013/02/t-sql-queries/halloween-problem-part-1

【讨论】:

  • 其实没有。第一次更新 (3) 的值不会是静态的。这将是一个复杂计算的结果,我不想在下一行更新中重复
  • 再一次,这只是一个例子......您计算一次值并在更新中使用它。如果这不起作用,那么您的问题不清楚,您应该提供一个更具代表性的示例......因为此解决方案适用于您提供的架构、数据和查询。我只能回答你提出的实际问题,而不是你脑海中的未知问题。
  • 想象我有 2 个表,我在第一行更新它们(通过连接),但在第二个中,我需要使用第二个表的更新值来获取正确的结果
【解决方案2】:

抱歉打扰各位了……我找到了问题的答案。这是一个例子:

create table #temp (col1 int, col2 int)

declare @var int = 3

insert into #temp values(1, 2)
insert into #temp values(2, 4)
insert into #temp values(3, 6)

update T set 
col2 = @var * col2,
@var = @var - 1 
from #temp T

【讨论】:

  • 这个方法被命名为quirky update,它有一些缺点。请阅读。
  • 无意冒犯,但这个“答案”似乎与问题没有任何关系,这不是关于“如何修改选择中每一行的变量”而是“如何我得到了我刚刚在同一次更新中分配给前一列的值”......您确实需要一个更好的问题陈述,包含实际数据和实际查询,以便人们能够理解和帮助。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-02-24
  • 2015-12-31
  • 1970-01-01
  • 1970-01-01
  • 2011-06-03
  • 2018-04-23
相关资源
最近更新 更多