Как назначить локальную переменную для локальной переменной в SQL Server

121
9

Предположим, что у меня есть номера таблиц:

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

Очевидно, что выше код неверен? Каков правильный способ сделать это?

спросил(а) 2018-08-15T05:59:00+03:00 2 года, 2 месяца назад
1
Решение
57

SQL Server не поддерживает определяемые пользователем переменные как таковые. С учетом сказанного вы можете добиться того же результата создания текущей суммы с помощью window function:

select number, sum(frequency) over (order by number)
from yourtable

В приведенном ниже комментарии, если вам нужна и предыдущая текущая сумма, вы можете использовать подзапрос с lag и 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

Это в основном просто создает несколько текущих сумм, один для предыдущей суммы.

ответил(а) 2018-08-15T06:12:00+03:00 2 года, 2 месяца назад
41

Конкретное утверждение, которое sgeddes хочет сказать, состоит в том, что SELECT в SQL Server может присваивать значения переменной или возвращать результаты, но не может делать оба. Код 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. Если вы хотите это исправить, задайте другой вопрос.

ответил(а) 2018-08-15T14:42:00+03:00 2 года, 2 месяца назад
Ваш ответ
Введите минимум 50 символов
Чтобы , пожалуйста,
Выберите тему жалобы:

Другая проблема