Reputation: 557
Suppose I have a table numbers:
number frequency
1 6
2 2
3 8
4 5
In MySQL, we can dynamically assign variable without declare
select
Number,
@prev := @count as prevNumber,
(@count := @count + Frequency) as countNumber
from Numbers
In SQL Server, can we do the same?
I have to declare and then use?
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
Obviously above code is incorrect? What is the correct way to do it?
Upvotes: 0
Views: 462
Reputation: 1270181
The specific statement that sgeddes wants to say is that a SELECT
statement in SQL Server can assign values to a variable or return results, but cannot do both. The MySQL code is doing both.
In SQL Server, you would do this using window functions. If you want the running sum up to but not including the current value, just subtract out the current value:
select number,
sum(frequency) over (order by number) as running_sum,
(sum(frequency) over (order by number) - frequency) as running_prev_sum
from yourtable;
You can also use a window clause:
sum(frequency) over (order by number rows between unbounded preceding and 1 preceding)
But I find that cumbersome and less clear than just subtracting the current value.
I need to also add that your MySQL is not guaranteed to work. MySQL does not guarantee the order of evaluation of expressions in a SELECT
. If you want to fix that, ask another question.
Upvotes: 0
Reputation: 62841
SQL Server doesn't support user-defined variables as such. With that said, you can achieve the same result of creating a running sum using a window function
:
select number, sum(frequency) over (order by number)
from yourtable
Per the comment below, if you need the previous running sum as well, you can use a subquery with lag
and coalesce
:
select number, sum(prevnum) over (order by number) as prevNumber, countNumber
from (select *, coalesce(lag(frequency) over (order by number),0) as prevnum,
sum(frequency) over (order by number) as countNumber
from yourtable) t
This basically just creates multiple running sums, one for the previous amount as well.
Upvotes: 1