【问题标题】:ORACLE SQL - How to find the number of reliefs each teacher has, each day, 2 months before the teacher resigned?ORACLE SQL - 如何找到每位教师在教师辞职前 2 个月内每天获得的救济数量?
【发布时间】:2019-08-02 02:10:22
【问题描述】:

我需要一些帮助来确定每位教师每天在教师辞职前 2 个月获得的救济数量。 Join_dt - 老师的加入日期, Resign_dt - 老师的辞职日期, Relief_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 = 1 因为Relief_ID 103。 对于日期 2017-07-04,No_of_reliefs = 2 因为Relief_ID 20 & 103。

日期应该从老师辞职前 1 个月开始。 Teacher_ID23,自2019-11-12辞职,日期从2019-10-31开始。

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

【问题讨论】:

    标签: sql oracle


    【解决方案1】:

    你可以使用

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

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

    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

    【讨论】:

      【解决方案2】:
      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
      

      【讨论】:

        猜你喜欢
        • 2023-03-31
        • 1970-01-01
        • 2023-01-28
        • 1970-01-01
        • 2021-02-18
        • 2017-09-17
        • 1970-01-01
        • 1970-01-01
        • 2016-02-06
        相关资源
        最近更新 更多