Вопросы и ответы по MS SQL Server

  Все выпуски  

Вопросы и ответы по MS SQL Server


Информационный Канал Subscribe.Ru


Вопросы и ответы по MS SQL Server

Выпуск No. 18 от 2003-06-20

Вопрос : Как в запросе обрабатывать данные предыдущей строки?

Ответ:
Иногда при составлении запросов необходимо знать данные, содержащиеся в предыдущей строке. Как правило для того, чтобы получить разницу значений колонки между строками.

Создадим таблицу продаж и построим запрос, в котором будут дополнительные колонки, содержащие даты предыдущих продаж, разницу между суммами продаж и количество дней между продажами:
CREATE TABLE #Sales

(
ClientID int,
Date datetime,
Amount money,
PRIMARY KEY CLUSTERED (ClientID, Date)
)
insert #Sales values(1,'20010401', 15.48)
insert #Sales values(1,'20020302', 134.01)
insert #Sales values(1,'20031003', 2346.03)
insert #Sales values(2,'20030203', 754.88)
insert #Sales values(3,'20010301', 73.07)
insert #Sales values(3,'20030402', 734.46)
insert #Sales values(4,'20010301', 1567.10)
insert #Sales values(4,'20020404', 6575.70)
insert #Sales values(4,'20030307', 6575.77)
insert #Sales values(4,'20030309', 6575.37)
insert #Sales values(5,'20011201', 1975.73)
insert #Sales values(5,'20030306', 178965.63)
insert #Sales values(6,'20020103', 16785.34)
insert #Sales values(6,'20030304', 1705.44)
GO

select a.ClientID, a.Date, b.Date, a.Amount,
a.Amount-b.Amount as DeltaAmount, DATEDIFF(d, b.Date, a.Date) as DeltaDate
from #Sales a
left join #Sales b on b.ClientID=a.ClientID
and b.Date=(
select max(Date)
from #Sales
where ClientID=a.ClientID and Date<a.Date
)
GO

DROP TABLE #Sales
GO

Результат:
ClientID Date       Date       Amount     DeltaAmount DeltaDate

-------- ---------- ---------- ---------- ----------- ---------
1 01.04.2001 NULL 15.48 NULL NULL
1 02.03.2002 01.04.2001 134.01 118.53 335
1 03.10.2003 02.03.2002 2346.03 2212.02 580
2 03.02.2003 NULL 754.88 NULL NULL
3 01.03.2001 NULL 73.07 NULL NULL
3 02.04.2003 01.03.2001 734.46 661.39 762
4 01.03.2001 NULL 1567.10 NULL NULL
4 04.04.2002 01.03.2001 6575.70 5008.60 399
4 07.03.2003 04.04.2002 6575.77 0.07 337
4 09.03.2003 07.03.2003 6575.37 -0.40 2
5 01.12.2001 NULL 1975.73 NULL NULL
5 06.03.2003 01.12.2001 178965.63 176989.90 460
6 03.01.2002 NULL 16785.34 NULL NULL
6 04.03.2003 03.01.2002 1705.44 -15079.90 425

(14 row(s) affected)


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

Таким образом, для построения подобных запросов необходимо иметь условие, согласно которому однозначно определяется положение строки в результате запроса. Если такого условия нет, и строки могут меняться местами без изменения сути запроса, то необходимо добавить искусственный столбец с уникальным ключом.
Надеюсь, Вы нашли эту информацию полезной. Вопросы, предложения и пожелания шлите на адрес sql@likor.ru
С уважением, Сергей Кошкин.
Архив рассылки смотрите на сайте Рассылки http://sql.softmatics.ru/
Рейтинг@Mail.ru

http://subscribe.ru/
E-mail: ask@subscribe.ru
Отписаться
Убрать рекламу

В избранное