ORACLE SQL-如何找到每位老师在辞职前2个月每天的减免额?

时间:2019-08-01 15:12:15

标签: sql oracle

在老师辞职前两个月的每一天,我需要一些帮助来确定每位老师的减免额。 Join_dt-老师的加入日期, Resign_dt-老师的辞职日期, Relief_ID-救济老师的ID, Start_dt-救济的开始日期, End_dt-救济的结束日期,

请注意,两个或更多个不同的浮雕之间可能存在重叠的日期,因此我需要找到每个日期的每个老师具有的不同浮雕的数量。

这就是我得到的:

Teacher_ID  Join_dt     Resign_dt   Relief_ID  Start_dt    End_dt      
12          2006-08-30  2019-08-01  20         2017-02-07  2019-07-04      
12          2006-08-30  2019-08-01  20         2016-11-10  2019-01-30      
12          2006-08-30  2019-08-01  103        2016-08-20  2019-07-29      
12          2006-08-30  2019-08-01  17         2016-01-30  2017-12-30      
23          2017-10-01  2018-11-12  44         2018-10-19  2018-11-11      
23          2017-10-01  2018-11-12  29         2018-04-01  2018-12-02      
23          2017-10-01  2018-11-12  06         2017-11-25  2018-05-02      
05          2015-02-11  2019-10-02  38         2019-01-17  2019-07-21      
05          2015-02-11  2019-10-02  11         2018-11-02  2019-02-05      
05          2015-02-11  2019-10-02  15         2018-09-30  2018-10-03 

预期结果:

Teacher_ID Dates       No_of_reliefs
12         2019-07-31  0
12         2019-07-30  0
12         2019-07-29  1
12         2019-07-28  1
12         2019-07-27  1
...        ...
12         2019-07-04  2
...        ...
12         2016-05-30  2
12         2016-05-29  2
12         2016-05-28  2
12         2016-05-27  2
12         2016-05-26  1 
23         2018-10-31  2
...        ...

对于日期2019-07-29,由于No_of_reliefs 103,Relief_ID = 1。 对于日期2017-07-04,由于No_of_reliefs 20和103,Relief_ID =2。

日期应从教师辞职前的1个月开始。对于Teacher_ID 23,自她于2019-11-12辞职以来,日期应从2019-10-31开始。

我尝试使用connect by,但是执行时间确实很长,因为它涉及大量数据。 任何其他方法将不胜感激! 谢谢你好心人!!

2 个答案:

答案 0 :(得分:2)

您可以使用

connect by level <= last_day(add_months(Resign_dt,-1)) - add_months(Resign_dt,-2)子句:

我想您的意思是在starting日期前辞职2个月,在上个月的最后一天ending辞职。

with t1(Teacher_ID,Resign_dt,Relief_ID,start_dt,end_dt) as
(
  select 12,date'2019-08-01',20 ,date'2017-02-07',date'2019-07-04' from dual union all      
  select 12,date'2019-08-01',20 ,date'2016-11-10',date'2019-01-30' from dual union all
  select 12,date'2019-08-01',103,date'2016-08-20',date'2019-07-29' from dual
 ......
), t2 as
(
 select distinct last_day(add_months(Resign_dt,-1)) - level + 1 as Resign_dt, Teacher_ID
   from t1
connect by level <= last_day(add_months(Resign_dt,-1)) - add_months(Resign_dt,-2)                         
    and prior Teacher_ID = Teacher_ID and prior sys_guid() is not null
)
select Teacher_ID, to_char(Resign_dt,'yyyy-mm-dd') as Dates,
       (select count(distinct Relief_ID) 
          from t1 
         where t2.Resign_dt between start_dt and end_dt
           and t2.Teacher_ID = Teacher_ID
        )
  from t2
 order by Teacher_ID, Resign_dt desc;

Demo

答案 1 :(得分:1)

select d.dt
, tr.Teacher_ID
--, tr.Join_dt
--, tr.Resign_dt
, count(tr.Relief_ID)
--, tr.Start_dt
--, tr.End_dt

from tr
  right outer join (
    SELECT dt

    FROM (
                    SELECT DATE '2006-01-01' + ROWNUM - 1 dt
                    FROM DUAL CONNECT BY ROWNUM < 5000
            ) q

    WHERE EXTRACT(YEAR FROM dt) < EXTRACT(YEAR FROM sysdate) + 2

    --order by 1
) d on d.dt between tr.Join_dt and tr.End_dt
   and d.dt between tr.Start_dt and tr.Resign_dt

group by d.dt
, tr.Teacher_ID

order by d.dt desc