SQL - 取决于日期

时间:2016-12-21 15:22:46

标签: sql oracle date

我有一个时间序列表,如下所示:

ID  Date        Value  
 1  2016-11-01    1.0 
 1  2016-11-03   1.76
...  

即。只是每个人的连续值。我也有这样一张桌子:

ID  class  Date   
 1  c1     2016-11-01
 1  c2     2016-12-02
 1  c3     2017-02-03
...

即。一个表,告诉ID属于哪个类。日期表示它开始应用的日期,然后应用到表格中的下一行(日期)。

我需要以某种方式将他们加入到一起,以便为“课程”提供完整的时间序列。专栏:

ID  class  Date        Value 
 1  c1     2016-11-01  1.0 
...
 1  c2     2016-12-02  2.5  
...
 1  c3     2017-02-03  3.7
...

有没有人有一个很好的解决方案/暗示如何实现这个?

1 个答案:

答案 0 :(得分:2)

这是Oracle的解决方案。根据需要进行调整。顶部不是解决方案的一部分(参见代码中的COMMENT);我只是用它来测试。我在第一个表中添加了一行以确认查询在第二个表中的最后一个日期之后的日期是否正常工作。此外,在Oracle 日期是保留字,因此不应将其用作列名。我将其更改为 dt

with 
     your_first_table ( id, dt, value ) as (
       select 1, date '2016-11-01', 1.0  from dual union all
       select 1, date '2016-11-03', 1.76 from dual union all
       select 1, date '2017-04-11', 2.34 from dual
     ),
     your_second_table ( id, class, dt ) as (
       select 1, 'c1', date '2016-11-01' from dual union all
       select 1, 'c2', date '2016-12-02' from dual union all
       select 1, 'c3', date '2017-02-03' from dual
     )
-- end of test data; SQL query begins below this line
select t1.id, t2.class, t1.dt, t1.value
from   your_first_table t1
       left outer join
       ( select id, class, dt as from_dt, 
                lead(dt) over (partition by id order by dt) as to_dt
         from   your_second_table
       ) t2
       on       t1.id  = t2.id
          and   t1.dt >= t2.from_dt
          and ( t1.dt  < t2.to_dt   or   t2.to_dt is null)
;

  ID CLASS DT              VALUE
---- ----- ---------- ----------
   1 c1    2016-11-01          1
   1 c1    2016-11-03       1.76
   1 c3    2017-04-11       2.34

3 rows selected.