Если вы просто хотите быстро и грязно, это будет делать:
select curr.*, prev.*
from EXPORT_TABLE curr
outer apply (
select top 1 * from EXPORT_TABLE prev
where curr.time_stamp > prev.time_stamp
order by time_stamp desc, id desc
) prev
И иди оттуда.
Но этот метод и некоторые аналогичные методы на этой странице, в которых используется неравномерное распределение, не будут хорошо масштабироваться с объемом. Чтобы обрабатывать большой объем данных, мы должны использовать разные методы.
Ваш идентификатор отображается последовательно. Это? Это может быть полезно. Если нет, мы должны создать его.
if object_id('tempdb..#pass1') is not null drop table #pass1
create table #pass1 (
id int
, time_stamp smalldatetime
, machine_state tinyint
, seqno int primary key -- this is important
)
insert #pass1
select
id
, time_stamp
, machine_state
, seqno = row_number() over (order by time_stamp, id)
from EXPORT_TABLE
Как только мы получим последовательный идентификатор, мы сможем присоединиться к нему:
if object_id('tempdb..#pass2') is not null drop table #pass2
create table #pass2 (
id int
, time_stamp smalldatetime
, machine_state tinyint
, seqno int primary key
, time_stamp_prev smalldatetime
)
insert #pass2
select
id
, time_stamp
, machine_state
, seqno
, time_stamp_prev = b.time_stamp
from #pass1 a
left join #pass1 b on a.seqno = b.seqno + 1
Отсюда ваш запрос должен написать сам. Однако обратите внимание на состояния машины, которые перекрывают смену.
Этот метод, хотя и выглядит дорогим, хорошо масштабируется с объемом. Вы заказываете данные один раз и присоединяетесь один раз. Если идентификатор является последовательным, вы можете пропустить первый шаг, убедиться, что есть кластерный первичный ключ для идентификатора, и присоединиться к идентификатору, а не к seqno.
Если у вас действительно большой объем данных, вы делаете это вместо этого:
if object_id('tempdb..#export_table') is not null drop table #export_table
create table #pass1 (
id int
, time_stamp smalldatetime
, machine_state tinyint
, seqno int primary key -- ensures proper ordering for the UPDATE
, time_stamp_prev smalldatetime
)
insert #export_table (
id
, time_stamp
, machine_state
, seqno
)
select
id
, time_stamp
, machine_state
, seqno = row_number() over (order by time_stamp, id)
from EXPORT_TABLE
-- do some magic
declare @time_stamp smalldatetime
update #export_table set
time_stamp_prev = @time_stamp
, @time_stamp = time_stamp
Это превзойдет все остальные методы. И если ваш идентификатор находится в правильном порядке (он не должен быть последовательным, просто в правильном порядке), вы можете пропустить первый шаг и вместо этого определить кластеризованный индекс для идентификатора, если он еще не существует.