如何为一系列日期运行特定日期查询

时间:2018-06-05 06:31:47

标签: sql oracle oracle11g

表格

table1 (mdate date, id1 number, id2 number, id3 number, description varchar2);--activity table 
table2 (id1 number ,id2 number, id3 number,flag number);                      --customer table  

(id1, id2 , id3)table2中的密钥和table1中的外键。

这是一个针对特定日期(:mydate)运行的查询,并从table1(活动)中返回已闲置2个月然后在指定日期重新出现的行(:mydate)。

select mdate, id3, id1, id2, description  
from table2 where (id1,id2, id3) in  
(
  select  id1,id2, id3  from table1 where --get the keys with flag=1 and no activity for 2 months 
    flag=1 and 
    not exists --no activity for 2 months before :mydate (not counting mydate) 
        (
            select 1 from  table2  where  
            mdate>=add_months(to_date(:mydate,'dd/mm/rrrr'),-2) --- activity 2 months ago  
            and mdate < to_date( :mydate,'dd/mm/rrrr') --- but not the given day   
            and table1.id1 =table2.id1 and table1.id2 = table2.id2 and table1.id3 = table2.id3
        )
    and exists 
        (
            select 1 from  table2  where    
            mdate = to_date( :mydate,'dd/mm/rrrr') -- activity on given day ( mydate)
            and table1.id1 =table2.id1 and table1.id2 = table2.id2 and table1.id3 = table2.id3
        )
 ) and mdate=:mydate --new activity 

因此,为... 01/06/2018可以给出结果

01/06/2018 1 1 1 'lights on'
01/06/2018 1 1 2 'power off'
01/06/2018 1 3 5 'sound off'

现在我需要相同的查询来运行一系列日期,例如从01/06/201803/06/2018

,结果应为

01/06/2018 1 1 1 'lights on'
01/06/2018 1 1 2 'power off'
01/06/2018 1 3 5 'sound off'

02/06/2018 1 5 1 'power on'
02/06/2018 1 7 2 'power off'
02/06/2018 1 9 5 'sound on'

03/06/2018 8 1 1 'lights off'
03/06/2018 5 1 2 'power  off'
03/06/2018 9 3 5 'sound  off'

就像上一次查询的3次运行一样。但是我应该能够在任何日期范围内运行它。

我可以通过使用管道功能实现上述功能 - 但我想要一个sql解决方案。 可能是某种递归/分层sql?

(我尝试使用connect bylevel,但没有获得所需的结果)

感谢。

1 个答案:

答案 0 :(得分:1)

使用WITH子句生成范围内的日期表,如下所示:

with cte as ( 
    select :start_date + (level-1) as mydate
    from dual
    connect by level <= (:end_date - :start_date) +1
)
select mdate, id3, id1, id2, description  
from cte 
     join table2 on table2.mdate = cte.mydate --new activity 
where (id1,id2, id3) in  
(
  select  id1,id2, id3  from table1 where --get the keys with flag=1 and no activity for 2 months 
    flag=1 and 
    not exists --no activity for 2 months before :mydate (not counting mydate) 
        (
            select 1 from  table2  where  
            mdate>=add_months(to_date(cte.mydate,'dd/mm/rrrr'),-2) --- activity 2 months ago  
            and mdate < to_date( cte.mydate,'dd/mm/rrrr') --- but not the given day   
            and table1.id1 =table2.id1 and table1.id2 = table2.id2 and table1.id3 = table2.id3
        )
    and exists 
        (
            select 1 from  table2  where    
            mdate = to_date( cte.mydate,'dd/mm/rrrr') -- activity on given day ( mydate)
            and table1.id1 =table2.id1 and table1.id2 = table2.id2 and table1.id3 = table2.id3
        )
 ) 

好的,我刚刚注意到你的问题是......

  

我尝试使用connect bylevel但未获得所需的结果

...此解决方案使用connect bylevel。 Hmmmm。幸运的是,这个解决方案与您的解决方案不同,但如果您仍未获得所需的结果,请发布更多详细信息。