LAG()
стал доступен в SQL 2012. Это позволяет вам взять текущую строку val
и вычесть val
из предыдущей строки, сгруппированные по id
и отсортированные по Time
. Это вернет NULL
для первых двух строк, так как у них нет предыдущей записи для сравнения. Вы можете исключить их, поместив запрос в подвыбор, затем применив WHERE valDiff IS NULL
, или вы можете по умолчанию valDiff
, используя третий аргумент LAG()
> LAG(Val,1,0)
, по умолчанию первые две строки равны 0
.
SQL Fiddle
Настройка схемы MS SQL Server 2017 :
CREATE TABLE t1 ( ID int, VAL int, [Time] datetime) ;
INSERT INTO t1 ( ID, Val, [Time] )
VALUES
( 2, 1 , '2015-05-09 12:54:39')
, ( 3, 10, '2015-05-09 12:54:39')
, ( 2, 1 , '2015-05-09 12:56:39')
, ( 3, 10, '2015-05-09 12:56:39')
, ( 2, 5 , '2015-05-09 13:48:30')
, ( 3, 16, '2015-05-09 13:48:30')
, ( 2, 7 , '2015-05-09 15:01:09')
, ( 3, 20, '2015-05-09 15:01:09')
;
Запрос 1 :
SELECT s1.ID
, s1.ValDiff
, FORMAT(s1.[Time], 'yyyy-MM-dd hh:mm:ss') AS fTime
FROM (
SELECT ID
, Val - LAG(Val,1) OVER ( PARTITION BY ID ORDER BY [Time],ID ) AS ValDiff
, [Time]
FROM t1
) s1
WHERE s1.valDiff IS NOT NULL
ORDER BY s1.[Time],s1.ID
Результаты
| ID | ValI | fTime |
|----|---------|---------------------|
| 2 | 0 | 2015-05-09 12:56:39 |
| 3 | 0 | 2015-05-09 12:56:39 |
| 2 | 4 | 2015-05-09 01:48:30 |
| 3 | 6 | 2015-05-09 01:48:30 |
| 2 | 2 | 2015-05-09 03:01:09 |
| 3 | 4 | 2015-05-09 03:01:09 |