Альтернатива функции опережающего отставания в SQL Server 2008

140
17

Я хочу сравнить текущую строку со значением в следующей строке. SQL имеет функции LEAD и LAG для получения следующих и предыдущих значений, но я не могу их использовать, потому что я использую SQL Server 2008.


Итак, как мне это получить?


У меня есть таблица с выходом


+----+-------+-----------+-------------------------+
| Id | ActId | StatusId | MinStartTime |
+----+-------+-----------+-------------------------+
| 1 | 42 | 1 | 2014-02-14 11:17:21.203 |
| 2 | 42 | 1 | 2014-02-14 11:50:19.367 |
| 3 | 42 | 1 | 2014-02-14 11:50:19.380 |
| 4 | 42 | 6 | 2014-02-17 05:25:57.280 |
| 5 | 42 | 6 | 2014-02-19 06:09:33.150 |
| 6 | 42 | 1 | 2014-02-19 06:11:24.393 |
| 7 | 42 | 6 | 2014-02-19 06:11:24.410 |
| 8 | 42 | 8 | 2014-02-19 06:44:47.070 |
+----+-------+-----------+-------------------------+

То, что я хочу сделать, - это состояние текущей строки 1, а состояние следующей строки равно 6, и оба раза одинаковы (до минут), тогда я хочу получить строку, в которой состояние равно 1.


Например: Id 6 row имеет статус 1, а строка Id 7 имеет статус 6, но оба раза совпадают, т.е. 2014-02-19 06:11


Итак, я хочу получить эту строку или идентификатор для статуса 1, т.е. id 6

спросил(а) 2014-03-05T07:26:00+04:00 6 лет, 6 месяцев назад
1
Решение
137

В вашем случае id представляется числовым, вы можете просто выполнить самоподключение:


select t.*
from table t join
table tnext
on t.id = tnext.id - 1 and
t.StatusId = 1 and
tnext.StatusId = 6 and
datediff(second, t.MinStartTime, tnext.MinStartTime) < 60;

Это не совсем та же минута. Это в течение 60 секунд. Вам действительно нужна та же самая минутка календаря? Если это так, вы можете сделать:


select t.*
from table t join
table tnext
on t.id = tnext.id - 1 and
t.StatusId = 1 and
tnext.StatusId = 6 and
datediff(second, t.MinStartTime, tnext.MinStartTime) < 60 and
datepart(minute, t.MinStartTime) = datepart(minute, tnext.MinStartTime);

ответил(а) 2014-03-05T07:31:00+04:00 6 лет, 6 месяцев назад
41

Ну, я бы предложил очень простое решение, если у вас нет идентификатора последовательной строки, но другого шага (если некоторые записи были удалены, например..):

declare @t table(id int, obj_name varchar(5))

insert @t select 1,'a'

insert @t select 5,'b'

insert @t select 22,'c'

insert @t select 543,'d'

---------------------------------
select *from @t

Пример исходной таблицы @t:

---------------------------------
id obj_name

1 a

5 b

22 c

543 d

---------------------------------

Выбрать с помощью самостоятельного подключения

select obj_name_prev=tt.obj_name, obj_name_next=min(t.obj_name)

from @t t

join @t tt on tt.id < t.id

group by tt.obj_name

Результат:

---------------------------------
obj_name_prev obj_name_next

a b

b c

c d

---------------------------------

ответил(а) 2018-02-08T17:38:00+03:00 2 года, 7 месяцев назад
40

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


SELECT 
fm0.SAMPLE curFMSample
, fm1.SAMPLE nextFMSample
, fm0.TEMPERATURE curFMTemp
, fm1.TEMPERATURE nextFMTemp
, ABS(CAST((fm0.Temperature - fm1.Temperature) AS DECIMAL(4, 0)) / CAST(fm0.TEMPERATURE AS DECIMAL(4, 0))) AS fmTempChange
, fm0.GAUGE curFMGauge
, fm1.GAUGE nextFMGauge
, ABS(CAST((fm0.GAUGE - fm1.GAUGE) AS DECIMAL(4, 4)) / CAST(fm0.GAUGE AS DECIMAL(4, 4))) AS fmGaugeChange
, fm0.WIDTH curFMWidth
, fm1.WIDTH nextFMWidth
, ABS(CAST((fm0.Width - fm1.Width) AS DECIMAL(4, 2)) / CAST(fm0.Width AS DECIMAL(4, 2))) AS fmWidthChange
, cl0.TEMPERATURE curClrTemp
, cl1.TEMPERATURE nextClrTemp
, ABS(CAST((cl0.Temperature - cl1.Temperature) AS DECIMAL(4, 0)) / CAST(cl0.TEMPERATURE AS DECIMAL(4, 0))) AS clrTempChange
FROM
dbo.COIL_FINISHING_MILL_EXIT_STR02 fm0
INNER JOIN dbo.COIL_FINISHING_MILL_EXIT_STR02 fm1 ON (fm0.SAMPLE = fm1.SAMPLE - 1 AND fm1.coil = fm0.coil)
INNER JOIN dbo.COIL_COILER_STR02 cl0 ON fm0.coil = cl0.coil AND fm0.SAMPLE = cl0.SAMPLE
INNER JOIN dbo.COIL_COILER_STR02 cl1 ON (cl0.SAMPLE = cl1.SAMPLE - 1 AND cl1.coil = cl0.coil)
WHERE
fm0.coil = 2015515872

ответил(а) 2015-09-23T18:15:00+03:00 5 лет назад
Ваш ответ
Введите минимум 50 символов
Чтобы , пожалуйста,
Выберите тему жалобы:

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