2016-05-26 4 views
0

Я уверен, что на это есть ответы, но я не совсем уверен, как его искать.Несколько объединений одной таблицы в SQL

У меня есть таблица, [tbl_Data], который выглядит следующим образом:

ID| From_Dt | To_Dt  | 
1 |01/01/2016 | 01/03/2016| 
1 |01/04/2016 | 01/09/2016| 
1 |01/09/2016 | 01/20/2016| 

Хочет выход выглядеть следующим образом:

ID|Prev_From_Dt|Prev_To_Dt |Recent_From_Dt|Recent_To_Dt| 
1 |01/01/2016 |01/03/2016 |01/04/2016 |01/09/2016 | 
1 |01/04/2016 |01/09/2016 |01/09/2016 |01/20/2016 | 

Это моя попытка коды:

SELECT 
    t1.ID, 
    Prev_From_DT = t1.FROM_DT, 
    Prev_To_DT = t1.TO_DT, 
    Recent_From_DT = t2.FROM_DT, 
    Recent_To_DT = t2.TO_DT 
FROM 
    tbl_Data t1 
    LEFT JOIN tbl_Data t2 on t1.ID = t2.ID AND t1.TO_DT <= t2.FROM_DT 
+1

Какую версию SQL вы используете? (MySQL, Postgres и т. Д.). Если это MySQL, то вы, вероятно, найдете это SO ответ полезным http://stackoverflow.com/questions/1284441/how-does-a-mysql-self-join-work (волшебная фраза «присоединяется» - стол, соединенный с собой). –

+0

Какой результат вы получаете с запросом, который вы пробовали? –

+0

Использование MSSQL. Предложенный запрос создает запись для каждого From_Dt, которая меньше, чем To_Dt. – CurlieQ1034

ответ

0

Вы можете рассчитать рябины, а затем join в предыдущей строке, чтобы получить текущую строку и следующую строку e в той же строке.

with rownums as (select *,row_number() over(partition by id order by from_dt) rn from t) 
select 
r1.id, 
r1.from_dt prev_from_dt,r1.to_dt prev_to_dt, 
r2.from_dt recent_from_dt,r2.to_dt recent_to_dt 
from rownums r1 
join rownums r2 on r1.rn = r2.rn-1 and r1.id=r2.id 

Или просто использовать функцию lead, чтобы получить значения на следующей строке.

select * from (
select id, 
from_dt prev_from_dt,to_dt prev_to_dt 
lead(from_dt) over(partition by id order by from_dt) recent_from_dt, 
lead(to_dt) over(partition by id order by from_dt) recent_to_dt 
from t) x 
where recent_from_dt is not null and recent_to_dt is not null 
Смежные вопросы