2014-11-08 87 views
0

我在Oracle数据库中的两个表:甲骨文加入在第一个表的日期,日期范围表中的第二个表

第一个表有一个日期范围,我需要帮助写一个SQL查询来发现所有来自第二个表的记录如下面的结果表中所示。日期的前四位数字是年份,最后两位是会话(10-Fall; 20-Spring; 30-Summer)。

1)表1

seqnum | min_date| max_date |c_id 

1  | 201210 | 201210 | 100  
1  | 201220 | 201330 | 150  
1  | 201410 | 201410 | 200 

2)表2

seqnum | b_date 

1  | 201210 
1  | 201220 
1  | 2
1  | 201310 
1  | 201320 
1  | 201330 
1  | 201410 
1  | 201420 
1  | 201430 

3)结果表

seqnum | b_date | c_id 

1  | 201210 | 100 
1  | 201220 | 150 
1  | 2| 150 
1  | 201310 | 150 
1  | 201320 | 150 
1  | 201330 | 150 
1  | 201410 | 200 
1  | 201420 | 200 
1  | 201430 | 200 

如果Table1具有仅在第一记录然后在Table2所有的日期必须是仅与c_id有关。

+0

表1和表2之间的关系是什么? – 2014-11-08 14:51:46

回答

0

为了尽可能简单地做到这一点越好:

select t2.seqnum, t2.b_date, coalesce(t1.c_id, t3.max_id) as c_id 
    from table2 t2 
    left outer join table1 t1 
    on t2.b_date between t1.min_date and t1.max_date 
    cross join (select max(c_id) as max_id from table1) t3 
    order by t1.c_id, t2.b_date 

SQLFiddle here

分享和享受。

0

小提琴:http://sqlfiddle.com/#!4/45c72/10/0

select t2.seqnum, 
     t2.b_date, 
     case when t2.b_date < min_rg then x.c_id 
      when t2.b_date > max_rg then y.c_id 
       else t1.c_id 
       end as c_id 
    from (select min(min_date) as min_rg, max(max_date) as max_rg from table1) z 
    join table1 x 
    on x.min_date = z.min_rg 
    join table1 y 
    on y.max_date = z.max_rg 
cross join table2 t2 
    left join table1 t1 
    on t2.b_date between t1.min_date and t1.max_date 
order by b_date 

当B_DATE对表2的比对表1的第一个MIN_DATE它会显示从最低MIN_DATE的表1 C_ID较低(在你的情况100,现在)。

当table2上的B_DATE高于table1上的最后一个MAX_DATE时,它将显示最高MAX_DATE(现在是200,现在是200)的table1中的C_ID。

0
with table1 as (
select 1 seqnum, 201210 min_date, 201210 max_date, 100 c_id from dual 
union all select 1, 201220, 201330, 150 from dual 
union all select 1, 201410, 201410, 200 from dual 
), 
table2 as (
select 1 seqnum, 201210 b_date from dual 
union all select 1, 201220 from dual 
union all select 1, 2from dual 
union all select 1, 201310 from dual 
union all select 1, 201320 from dual 
union all select 1, 201330 from dual 
union all select 1, 201410 from dual 
union all select 1, 201420 from dual 
union all select 1, 201430 from dual 
),  
semi as (
select t2.seqnum, t2.b_date, t1.c_id, 
     -- since Oracle 11g 
     --lag(c_id IGNORE NULLS) over(partition by t2.seqnum order by t2.b_date) prev_c_id 
     last_value(c_id IGNORE NULLS) over(partition by t2.seqnum 
              order by t2.b_date 
              ROWS BETWEEN UNBOUNDED PRECEDING 
                AND 1 PRECEDING) prev_c_id 
from table2 t2 left join table1 t1 
    on t2.seqnum = t1.seqnum and t2.b_date between t1.min_date and t1.max_date 
) 
select seqnum, b_date, nvl(c_id, prev_c_id) c_id 
from semi; 

这可以通过分析函数来完成。

  1. LEFT JOIN表2表1与

  2. 以前计算(行由b_date订购)NOT NULL的c_id与(LAGLAST_VALUE +窗口)每个seqnum值。

  3. 如果c_id为NULL,则显示第一个非空的前一个值。

相关问题