Сложное самосоединение

#sql #sql-server #view #self-join

#sql #sql-сервер #Вид #самосоединение

Вопрос:

У меня проблема с представлением, я работаю с Sql Server. У меня есть таблица, подобная этой:

  ------- ------ 
| Start | End  |
 ------- ------ 
|     1 | Null |
|     3 | 4    |
|     6 | 9    |
 ------- ------ 
  

Эта таблица представляет собой последовательность таймфреймов, если End равен нулю, это означает, что она не завершена, но могут быть короткие перерывы (3-4 и 6-9), я хотел бы создать представление, которое будет отображать все таймфреймы следующим образом:

  ------- ------ 
| Start | End  |
 ------- ------ 
|     1 | 3    |
|     3 | 4    |
|     4 | 6    |
|     6 | 9    |
|     9 | Null |
 ------- ------ 
  

Я не могу найти решение. Я пытался более часа безрезультатно.

Ответ №1:

Я думаю, вы хотите union all с lead() :

 select start, lead(start) over (order by start)
from ((select t.start as start from likethis t
      ) union all
      (select t.end from likethis t
      )
     ) t
where start is not null
order by start;
  

В более ранних версиях SQL Server вы можете использовать cross apply :

 with t as (
      select t.start as start from likethis t
      union all
      select t.end from likethis t
     )
select t.start, tnext.start 
from t cross apply
     (select top 1 t2.*
      from t t2
      where t2.start > t.start
      order by t2.start desc
     ) tnext
order by start;
  

Комментарии:

1. WHERE Start IS NOT NULL в противном случае мы получим NULL значение из END столбца в результате

2. Существует проблема, на рабочем сервере установлена версия sql 2008… Есть ли какая-то альтернатива lead?