#sql #sql-server #sql-server-2008-r2
#sql #sql-сервер #sql-server-2008-r2
Вопрос:
Я пытаюсь определить, каким было значение счета за предыдущие месяцы, и поместить его в ту же строку, что и текущее значение.
Я использую SQL Server.Microsoft SQL Server 2008 R2 (SP2)
Я испытал свою удачу, используя CTE и всевозможные странные объединения, но мой вывод никогда не бывает правильным. Может кто-нибудь указать мне правильное направление?
Пример таблицы:
invoice_month value
--------------------------
201510 337265.386
201511 335466.456
201512 338646.500
201601 333440.380
201602 330731.208
201603 339299.752
201604 340878.168
201605 359585.382
201606 339616.430
201607 316457.486
201608 308009.976
201609 232196.268
201610 894839.180
201611 232196.268
201612 232196.268
201701 232196.268
201702 232196.268
201703 232196.268
Ожидаемый результат будет:
invoice_month value, prevValue
--------------------------------------------
201510 337265.386, NULL
201511 335466.456, 337265.386
201512 338646.500, 335466.456
201601 333440.380, 333440.380
201602 330731.208, 333440.380
201603 339299.752, 330731.208
201604 340878.168, 339299.752
201605 359585.382, 340878.168
201606 339616.430, 359585.382
201607 316457.486, 339616.430
201608 308009.976, 316457.486
201609 232196.268, 308009.976
201610 894839.180, 232196.268
201611 232196.268, 894839.180
201612 232196.268, 232196.268
201701 232196.268, 232196.268
201702 232196.268, 232196.268
201703 232196.268, 232196.268
Комментарии:
1. Правильно поставленный вопрос, но в вопросах SQL Server действительно полезно знать, на какой версии вы работаете, поскольку сложные / невозможные вещи могут внезапно стать возможными / легкими с новыми функциями.
Ответ №1:
В SQL Server 2012 вы бы использовали lag()
:
select t.invoice_month, t.value,
lag(t.value) over (order by t.invoice_month) as prev_value
from t;
Это стандартная функция ANSI. В более ранних версиях SQL Server существуют альтернативные методы.
Ответ №2:
для версий до 2012:
;with cte
as
(select invoice_month,value,
row_number() over (order by invoice_month) as rn
from #temp )
select c1.*,c2.value
from cte c1
left join
cte c2
on c1.rn=c2.rn 1
Ответ №3:
SELECT *
FROM (SELECT TOP 1 invoice_month,
value,
NULL AS [Previous value]
FROM Invoice
ORDER BY invoice_month ASC) T
UNION
SELECT I.invoice_month,
I.value,
I1.value AS [Previous value]
FROM Invoice I
INNER JOIN Invoice I1
ON I.invoice_month - 1 = I1.invoice_month