如何在SQL Server中将局部变量分配给局部变量

如何在SQL Server中将局部变量分配给局部变量,sql,sql-server,Sql,Sql Server,假设我有一个表编号: number frequency 1 6 2 2 3 8 4 5 在MySQL中,我们可以动态地分配变量而无需声明 select Number, @prev := @count as prevNumber, (@count := @count + Frequency) as countNumber from Numbers 在SQL Server中,我们也可以这样做吗 我必须申报然后使用吗 declare

假设我有一个表编号:

number  frequency
1        6
2        2
3        8
4        5
在MySQL中,我们可以动态地分配变量而无需声明

select 
Number, 
@prev := @count as prevNumber, 
(@count := @count + Frequency) as countNumber
from Numbers
在SQL Server中,我们也可以这样做吗

我必须申报然后使用吗

declare @prev int
declare @counts int
set @prev=0
set @counts=0

select number,
(@prev=@counts) as prevNumber,
(@counts=@counts+frquency) as countNumber from numbers

显然上面的代码是不正确的?正确的方法是什么?

SQL Server不支持用户定义的变量。也就是说,您可以使用窗口函数实现创建运行总和的相同结果:

根据下面的注释,如果还需要上一次运行的sum,可以使用带有lag和coalesce的子查询:

这基本上只是创建了多个运行总和,一个用于之前的金额


sgeddes想说的具体语句是,SQL Server中的SELECT语句可以为变量赋值或返回结果,但不能同时执行这两个操作。MySQL代码同时做这两件事

在SQL Server中,可以使用窗口函数来完成此操作。如果希望运行总和等于但不包括当前值,只需减去当前值:

select number,
       sum(frequency) over (order by number) as running_sum,
       (sum(frequency) over (order by number) - frequency) as running_prev_sum
from yourtable;
也可以使用窗口子句:

sum(frequency) over (order by number rows between unbounded preceding and 1 preceding)
但我发现这比仅仅减去当前值更麻烦、更不清晰


我还需要补充一点,您的MySQL不能保证工作。MySQL不保证SELECT中表达式的求值顺序。如果你想解决这个问题,可以问另一个问题。

OP似乎也想要一个在无界前置和1个前置数字之间的行。@ZLK-Hmm,我想这只是为了得到运行和。但是,如果OP需要该值,这里有一个使用lag的替代选项:SQL Server不支持用户定义的变量本身-这是一个大胆的说法,除非您对变量的定义与其他变量的定义有所不同。@RogerWolf-我不想说SQL Server不支持变量,只是当直接在sql语句中使用mysql允许的计算时,情况并非如此。当然,例如sql server支持存储过程中的变量,但据我所知,OP并不是在寻找这些变量。我的理解是OP在问如何在sql server中创建一个运行求和。@sgeddes,OP在问2个不同的问题而不是1个问题时肯定增加了一些混乱。尽管如此,我还是建议您改写引用的句子,因为它可能会在当前给出的方式中产生很多争议。您提供了样本数据,但您希望最终得到什么样的结果?
select number,
       sum(frequency) over (order by number) as running_sum,
       (sum(frequency) over (order by number) - frequency) as running_prev_sum
from yourtable;
sum(frequency) over (order by number rows between unbounded preceding and 1 preceding)