Присоединиться и заполнить значения NULL последним ненулевым
Я пытался соединиться, что сначала я считал относительно простым, но сейчас у меня возникли некоторые проблемы с получением правильного соединения. У меня есть два набора данных, которые напоминают следующие
ID | stmt_dt ID | renewal_dt
-- --
1 |1/31/15 1 | 2/28/15
1 |2/28/15 1 | 4/30/15
1 |3/31/15 2 | 2/28/15
1 |4/30/15 3 | 1/31/15
1 |5/31/15
2 |1/31/15
2 |2/28/15
2 |3/31/15
2 |4/30/15
2 |5/31/15
3 |1/31/15
3 |2/28/15
3 |3/31/15
3 |4/30/15
3 |5/31/15
4 |1/31/15
4 |2/28/15
4 |3/31/15
4 |4/30/15
4 |5/31/15
Вот мой желаемый вывод
ID | stmt_dt | renewal_dt
--
1 |1/31/15 | NA
1 |2/28/15 | 2/28/15
1 |3/31/15 | 2/28/15
1 |4/30/15 | 4/30/15
1 |5/31/15 | 4/30/15
2 |1/31/15 | NA
2 |2/28/15 | 2/28/15
2 |3/31/15 | 2/28/15
2 |4/30/15 | 2/28/15
2 |5/31/15 | 2/28/15
3 |1/31/15 | 1/31/15
3 |2/28/15 | 1/31/15
3 |3/31/15 | 1/31/15
3 |4/30/15 | 1/31/15
3 |5/31/15 | 1/31/15
4 |1/31/15 | NA
4 |2/28/15 | NA
4 |3/31/15 | NA
4 |4/30/15 | NA
4 |5/31/15 | NA
Моя самая большая проблема заключалась в том, чтобы получить объединенные значения для заполнения до следующего ненулевого значения в каждой группе. Любые идеи о том, как добиться этого присоединения? Спасибо!
3 ответа
ВЫБЕРИТЕ коррелированный запрос
select s.ID
,s.stmt_dt
,(
select max (r.renewal_dt)
from renewal r
where r.ID = s.ID
and r.renewal_dt <= s.stmt_dt
) as renewal_dt
from stmt s
order by ID
,stmt_dt
+----+------------+------------+
| ID | stmt_dt | renewal_dt |
+----+------------+------------+
| 1 | 2015-01-31 | |
| 1 | 2015-02-28 | 2015-02-28 |
| 1 | 2015-03-31 | 2015-02-28 |
| 1 | 2015-04-30 | 2015-04-30 |
| 1 | 2015-05-31 | 2015-04-30 |
| 2 | 2015-01-31 | |
| 2 | 2015-02-28 | 2015-02-28 |
| 2 | 2015-03-31 | 2015-02-28 |
| 2 | 2015-04-30 | 2015-02-28 |
| 2 | 2015-05-31 | 2015-02-28 |
| 3 | 2015-01-31 | 2015-01-31 |
| 3 | 2015-02-28 | 2015-01-31 |
| 3 | 2015-03-31 | 2015-01-31 |
| 3 | 2015-04-30 | 2015-01-31 |
| 3 | 2015-05-31 | 2015-01-31 |
| 4 | 2015-01-31 | |
| 4 | 2015-02-28 | |
| 4 | 2015-03-31 | |
| 4 | 2015-04-30 | |
| 4 | 2015-05-31 | |
+----+------------+------------+
объединить все + last_value
select ID
,dt as stmt_dt
,last_value (case when tab = 'R' then dt end ignore nulls) over
(
partition by id
order by dt
,case tab when 'R' then 1 else 2 end
) as renewal_dt
from ( select 'S',ID,stmt_dt from stmt
union all select 'R',ID,renewal_dt from renewal
) as t (tab,ID,dt)
qualify tab = 'S'
order by ID
,stmt_dt
+----+------------+------------+
| ID | stmt_dt | renewal_dt |
+----+------------+------------+
| 1 | 2015-01-31 | |
| 1 | 2015-02-28 | 2015-02-28 |
| 1 | 2015-03-31 | 2015-02-28 |
| 1 | 2015-04-30 | 2015-04-30 |
| 1 | 2015-05-31 | 2015-04-30 |
| 2 | 2015-01-31 | |
| 2 | 2015-02-28 | 2015-02-28 |
| 2 | 2015-03-31 | 2015-02-28 |
| 2 | 2015-04-30 | 2015-02-28 |
| 2 | 2015-05-31 | 2015-02-28 |
| 3 | 2015-01-31 | 2015-01-31 |
| 3 | 2015-02-28 | 2015-01-31 |
| 3 | 2015-03-31 | 2015-01-31 |
| 3 | 2015-04-30 | 2015-01-31 |
| 3 | 2015-05-31 | 2015-01-31 |
| 4 | 2015-01-31 | |
| 4 | 2015-02-28 | |
| 4 | 2015-03-31 | |
| 4 | 2015-04-30 | |
| 4 | 2015-05-31 | |
+----+------------+------------+
мин (...) более (... строк от 1 до 1 после 1)* + объединение
* = ВЕДУЩИЙ
select s.ID
,s.stmt_dt
,r.renewal_dt
from stmt s
left join (select ID
,renewal_dt
,min (renewal_dt) over
(
partition by ID
order by renewal_dt
rows between 1 following
and 1 following
) as next_renewal_dt
from renewal
) r
on s.ID = r.ID
and s.stmt_dt >= r.renewal_dt
and s.stmt_dt < coalesce (r.next_renewal_dt,date '9999-01-01')
order by s.ID
,s.stmt_dt
+----+------------+------------+
| ID | stmt_dt | renewal_dt |
+----+------------+------------+
| 1 | 2015-01-31 | |
| 1 | 2015-02-28 | 2015-02-28 |
| 1 | 2015-03-31 | 2015-02-28 |
| 1 | 2015-04-30 | 2015-04-30 |
| 1 | 2015-05-31 | 2015-04-30 |
| 2 | 2015-01-31 | |
| 2 | 2015-02-28 | 2015-02-28 |
| 2 | 2015-03-31 | 2015-02-28 |
| 2 | 2015-04-30 | 2015-02-28 |
| 2 | 2015-05-31 | 2015-02-28 |
| 3 | 2015-01-31 | 2015-01-31 |
| 3 | 2015-02-28 | 2015-01-31 |
| 3 | 2015-03-31 | 2015-01-31 |
| 3 | 2015-04-30 | 2015-01-31 |
| 3 | 2015-05-31 | 2015-01-31 |
| 4 | 2015-01-31 | |
| 4 | 2015-02-28 | |
| 4 | 2015-03-31 | |
| 4 | 2015-04-30 | |
| 4 | 2015-05-31 | |
+----+------------+------------+