Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Microsoft SQL Server Новый топик    Ответить
 Разница с предыдущим значением.  [new]
Dennis S.
Member

Откуда:
Сообщений: 82
Здравствуйте. Знаю, точно было, но после девяти страниц поиска не нашел приемлемого решения.

Есть таблица, в которой каждый день (однажды за день) хранятся некие показания нарастающим итогом.
#прибора Дата Счетчик
101.02.20135639665471
102.02.20135639684280
103.02.20135639686811
104.02.20135639707526
105.02.20135639745992
106.02.20135639745992
107.02.20135639776280
108.02.20135639782690
109.02.20135639803262
110.02.20135639806865
111.02.20135639817424
112.02.20135639843556
113.02.20135639853243
114.02.20135639878326
115.02.20135639920623
116.02.20135639951206
117.02.20135639972545


Мне нужна разница между текущим значением и значением на день раньше.

2008 сервер. О LAG/LEAD в 2012-м сервере знаю, но в 2008 - нет такого или я не знаю о них.
19 фев 13, 17:28    [13950356]     Ответить | Цитировать Сообщить модератору
 Re: Разница с предыдущим значением.  [new]
Паганель
Member

Откуда: Винница
Сообщений: 22550
ROW_NUMBER по дате(на случай дыр), а потом left join c самим собой по этому номеру
19 фев 13, 17:37    [13950416]     Ответить | Цитировать Сообщить модератору
 Re: Разница с предыдущим значением.  [new]
Dennis S.
Member

Откуда:
Сообщений: 82
Спасибо. А примером на sql?
19 фев 13, 17:38    [13950424]     Ответить | Цитировать Сообщить модератору
 Re: Разница с предыдущим значением.  [new]
Паганель
Member

Откуда: Винница
Сообщений: 22550
Dennis S.
Спасибо. А примером на sql?
давайте скрипт создания тестовой таблицы и заполнения ее тестовыми данными
19 фев 13, 17:39    [13950430]     Ответить | Цитировать Сообщить модератору
 Re: Разница с предыдущим значением.  [new]
Dennis S.
Member

Откуда:
Сообщений: 82
create table tmp 
([#no] integer, [#date] datetime, [#HP] float);
insert into tmp values (1, '01.02.2013', 5639665471);
insert into tmp values (1, '02.02.2013', 5639711183);
insert into tmp values (1, '03.02.2013', 5639749468);
insert into tmp values (1,'04.02.2013',5639795275);
insert into tmp values (1,'05.02.2013',5639828833);
insert into tmp values (1,'06.02.2013',5639828833);
insert into tmp values (1,'07.02.2013',5639833455);
insert into tmp values (1,'08.02.2013',5639844753);
insert into tmp values (1,'09.02.2013',5639888395);
insert into tmp values (1,'10.02.2013',5639929477);
insert into tmp values (1,'11.02.2013',5639962087);
insert into tmp values (1,'12.02.2013',5639965465);
insert into tmp values (1,'13.02.2013',5639979968);
insert into tmp values (1,'14.02.2013',5640021140);
insert into tmp values (1,'15.02.2013',5640066578);
insert into tmp values (1,'16.02.2013',5640087995);
insert into tmp values (1,'17.02.2013',5640117295);
insert into tmp values (2,'01.02.2013',65484215);
insert into tmp values (2,'02.02.2013',65512228);
insert into tmp values (2,'03.02.2013',65554909);
insert into tmp values (2,'04.02.2013',65559396);
insert into tmp values (2,'05.02.2013',65607282);
insert into tmp values (2,'06.02.2013',65622411);
insert into tmp values (2,'07.02.2013',65658555);
insert into tmp values (2,'08.02.2013',65697697);
insert into tmp values (2,'09.02.2013',65701456);
insert into tmp values (2,'10.02.2013',65739808);
insert into tmp values (2,'11.02.2013',65757430);
insert into tmp values (2,'12.02.2013',65760445);
insert into tmp values (2,'13.02.2013',65805643);
insert into tmp values (2,'14.02.2013',65805643);
insert into tmp values (2,'15.02.2013',65814031);
insert into tmp values (2,'16.02.2013',65830350);
insert into tmp values (2,'17.02.2013',65859841);


Как-то так.
19 фев 13, 18:28    [13950746]     Ответить | Цитировать Сообщить модератору
 Re: Разница с предыдущим значением.  [new]
Паганель
Member

Откуда: Винница
Сообщений: 22550
;with cte as(
   select row_number() over(partition by [#no] order by [#date]) as rn
         ,[#no], [#date], [#HP]
     from tmp
)
select c.[#no], c.[#date], c.[#HP], p.[#HP], c.[#HP] - p.[#HP]
  from cte as c
  left join cte as p on p.rn + 1 = c.rn
                    and p.[#no] = c.[#no]
тестируйте...
19 фев 13, 18:34    [13950770]     Ответить | Цитировать Сообщить модератору
 Re: Разница с предыдущим значением.  [new]
Dennis S.
Member

Откуда:
Сообщений: 82
Паганель на тестовой получилось.
А вот как привязаться к конкретной дате? грубо говоря отчет за 14 февраля:
#no#date#HP
12013-02-14 00:00:00.00041172
22013-02-14 00:00:00.0000
19 фев 13, 18:49    [13950826]     Ответить | Цитировать Сообщить модератору
 Re: Разница с предыдущим значением.  [new]
Паганель
Member

Откуда: Винница
Сообщений: 22550
 where c.[#date] >= '20130214'
   and c.[#date] < '20130215'
19 фев 13, 18:54    [13950850]     Ответить | Цитировать Сообщить модератору
 Re: Разница с предыдущим значением.  [new]
Dennis S.
Member

Откуда:
Сообщений: 82
Ухтышка!
Работает.

Разобрался с куда сувать дополнительные условия, но физический смысл последнего условия от меня ускользнул. Можно объяснить?
19 фев 13, 19:23    [13950968]     Ответить | Цитировать Сообщить модератору
 Re: Разница с предыдущим значением.  [new]
Паганель
Member

Откуда: Винница
Сообщений: 22550
datetime в принципе может содержать еще и время
19 фев 13, 19:27    [13950977]     Ответить | Цитировать Сообщить модератору
 Re: Разница с предыдущим значением.  [new]
Dennis S.
Member

Откуда:
Сообщений: 82
Вдогонку возник вопрос:
А если показателей нарастающим более одного, конкретно пять? Как вывести пять разниц?

create table tmp 
([#no] integer, [#date] datetime, [#HP] float, [#SECND] float, [#THRD] float, [#FORTH] float, [#FFTH] float);
insert into tmp values (1, '01.02.2013',5639665471,78547777,787556,342342,342456);
insert into tmp values (1, '02.02.2013',5639711183,78553440,795454,359186,348116);
insert into tmp values (1, '03.02.2013',5639749468,78569070,802180,374677,362820);
insert into tmp values (1, '04.02.2013',5639795275,78570606,820966,377911,374336);
insert into tmp values (1, '05.02.2013',5639828833,78576330,836062,385231,389505);
insert into tmp values (1, '06.02.2013',5639828833,78576330,836062,385231,389505);
insert into tmp values (1, '07.02.2013',5639833455,78588547,852045,399596,401248);
insert into tmp values (1, '08.02.2013',5639844753,78600202,863887,414311,409673);
insert into tmp values (1, '09.02.2013',5639888395,78611622,869471,431699,419046);
insert into tmp values (1, '10.02.2013',5639929477,78624665,878865,444291,434552);
insert into tmp values (1, '11.02.2013',5639929477,78624665,878865,444291,434552);
insert into tmp values (1, '12.02.2013',5639965465,78641142,888116,449524,449854);
insert into tmp values (1, '13.02.2013',5639979968,78648723,906948,455809,451293);
insert into tmp values (1, '14.02.2013',5640021140,78668212,918984,463012,469089);
insert into tmp values (1, '15.02.2013',5640066578,78671572,932764,476067,485316);
insert into tmp values (1, '16.02.2013',5640087995,78674940,934836,482080,493469);
insert into tmp values (1, '17.02.2013',5640117295,78692252,936293,490539,505935);
insert into tmp values (2, '01.02.2013',65484215,7879899,887445,324545,4322322);
insert into tmp values (2, '02.02.2013',65512228,7898063,892349,334041,4336113);
insert into tmp values (2, '03.02.2013',65554909,7905590,895565,337842,4342394);
insert into tmp values (2, '04.02.2013',65559396,7910882,908374,355856,4358936);
insert into tmp values (2, '05.02.2013',65607282,7930159,913850,372541,4378132);
insert into tmp values (2, '06.02.2013',65622411,7947833,932214,386820,4385649);
insert into tmp values (2, '07.02.2013',65658555,7951739,947652,391506,4392201);
insert into tmp values (2, '08.02.2013',65697697,7957060,955316,392852,4397753);
insert into tmp values (2, '09.02.2013',65701456,7976140,970145,403798,4415691);
insert into tmp values (2, '10.02.2013',65739808,7979577,989385,420857,4420865);
insert into tmp values (2, '11.02.2013',65757430,7991322,1003228,434599,4435429);
insert into tmp values (2, '12.02.2013',65760445,8001953,1011514,454041,4447184);
insert into tmp values (2, '13.02.2013',65805643,8012921,1016965,455904,4455695);
insert into tmp values (2, '14.02.2013',65805643,8012921,1016965,455904,4455695);
insert into tmp values (2, '15.02.2013',65814031,8026390,1036917,469228,4472447);
insert into tmp values (2, '16.02.2013',65830350,8037143,1055856,474128,4476815);
insert into tmp values (2, '17.02.2013',65859841,8042221,1062100,485451,4489276);
4 мар 13, 21:42    [14011005]     Ответить | Цитировать Сообщить модератору
 Re: Разница с предыдущим значением.  [new]
alexeyvg
Member

Откуда: Moscow
Сообщений: 31959
Dennis S.
А если показателей нарастающим более одного, конкретно пять? Как вывести пять разниц?
точно так же

c.[#HP] - p.[#HP],
c.[#SECND] - p.[#SECND], 
c.[#THRD] - p.[#THRD], 
c.[#FORTH] - p.[#FORTH], 
c.[#FFTH] - p.[#FFTH]

Только не спрашивайте про шесть значений! :-)
4 мар 13, 22:32    [14011136]     Ответить | Цитировать Сообщить модератору
 Re: Разница с предыдущим значением.  [new]
Dennis S.
Member

Откуда:
Сообщений: 82
alexeyvg , спасибо!
Я зачем-то начал добавлять джойны вместо разности.
4 мар 13, 22:51    [14011189]     Ответить | Цитировать Сообщить модератору
 Re: Разница с предыдущим значением.  [new]
Dennis S.
Member

Откуда:
Сообщений: 82
Возник вдогонку еще один вопрос - ситуация обнуления значений. В течение дня есть стартовое значение, значение перед обнулением, ноль и значение на конец дня. Как получить сумму двух нарастающих итогов за день? Со старта до обнуления и от нуля до конца дня?
27 мар 13, 16:32    [14102945]     Ответить | Цитировать Сообщить модератору
 Re: Разница с предыдущим значением.  [new]
iiyama
Member

Откуда:
Сообщений: 642
1) В datetime есть еще и time
2) и понадобится case
27 мар 13, 16:41    [14103004]     Ответить | Цитировать Сообщить модератору
 Re: Разница с предыдущим значением.  [new]
zozozozozo
Guest
Dennis S.,

with tbl
as
(
select m.*
from (values
	
		(1,	cast('20130201' as date),	5639665471),
		(1,	cast('20130202' as date),	5639684280),
		(1,	cast('20130203' as date),	5639686811),
		(1,	cast('20130204' as date),	5639707526),
		(1,	cast('20130205' as date),	5639745992)
	) as m(id, [date], cnt)
)
select
	t1.id,
	t1.date,
	t1.cnt,
	t1.cnt -
	(
		select top(1) t2.cnt
		from
			tbl t2
		where
			t2.[date] < t1.[date]
		order by [date] desc
	) as diff
from
	tbl as t1;
27 мар 13, 18:22    [14103671]     Ответить | Цитировать Сообщить модератору
 Re: Разница с предыдущим значением.  [new]
zozozozozo
Guest
zozozozozo,

+
			and t2.id = t1.id
27 мар 13, 18:30    [14103699]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft SQL Server Ответить