Search code examples
oracle-databasedateoracle11gdual-table

Arrange the date query result [oracle 11g]


This is my query to get all possible dates between two dates based on days.

    select A.presentationID,
       A.PRESENTATIONDAY,
       TO_CHAR(A.PRESENTATIONDATESTART+delta,'DD-MM-YYYY','NLS_CALENDAR=GREGORIAN') LIST_DATE
from 
  PRESENTATION A, 
  (
     select level-1 as delta 
     from dual 
     connect by level-1 <= (
       select max(PRESENTATIONDATEEND- PRESENTATIONDATESTART) from PRESENTATION
     )
  )
where A.PRESENTATIONDATESTART+delta <= A.PRESENTATIONDATEEND
and
  a.presentationday = trim(to_char(A.PRESENTATIONDATESTART+delta, 'Day'))
order by 1,2,3;

The values are retrieved from presentation table which consist of presentationday, presentationdatestart and presentationdateend.

Result from this query is :

622 Monday  02-05-2016 12:00:00
622 Monday  09-05-2016 12:00:00
622 Monday  16-05-2016 12:00:00
622 Monday  23-05-2016 12:00:00
622 Monday  30-05-2016 12:00:00
623 Tuesday 03-05-2016 12:00:00
623 Tuesday 10-05-2016 12:00:00
623 Tuesday 17-05-2016 12:00:00
623 Tuesday 24-05-2016 12:00:00
623 Tuesday 31-05-2016 12:00:00
624 Wednesday   04-05-2016 12:00:00
624 Wednesday   11-05-2016 12:00:00
624 Wednesday   18-05-2016 12:00:00
624 Wednesday   25-05-2016 12:00:00
624 Wednesday   01-06-2016 12:00:00
625 Thursday    05-05-2016 12:00:00
625 Thursday    12-05-2016 12:00:00
625 Thursday    19-05-2016 12:00:00
625 Thursday    26-05-2016 12:00:00
625 Thursday    02-06-2016 12:00:00

How can I arrange these value into something like this:

    622 Monday      02-05-2016     
    623 Tuesday     03-05-2016     
    624 Wednesday   04-05-2016     
    625 Thursday    05-05-2016     
    622 Monday      09-05-2016     
    623 Tuesday     10-05-2016  
    624 Wednesday   11-05-2016    
    625 Thursday    12-05-2016 
    622 Monday      16-05-2016 
    ....
    625 Thursday    02-06-2016 

Solution

  • I think you're just after this:

    select   a.presentationid,
             a.presentationday,
             to_char (a.presentationdatestart + delta, 'DD-MM-YYYY', 'NLS_CALENDAR=GREGORIAN') list_date
    from     presentation a,
             (select     level - 1 as delta
              from       dual
              connect by level - 1 <= (select max (presentationdateend - presentationdatestart)
                                       from   presentation))
    where    a.presentationdatestart + delta <= a.presentationdateend
    and      a.presentationday = to_char(a.presentationdatestart + delta, 'fmDay')
    order by a.presentationdatestart + delta,
             a.presentationid;
    

    N.B. note how I've removed your trim() and replaced it with fm in the format mask.

    P.S. You could rewrite your query to remove the join condition (and extra call to the presentation table) by doing it like so:

    with presentation as (select 622 presentationid, 'Monday' presentationday, to_date('01/05/2016', 'dd/mm/yyyy') presentationdatestart, to_date('31/05/2016', 'dd/mm/yyyy') presentationdateend from dual union all
                          select 623 presentationid, 'Tuesday' presentationday, to_date('01/05/2016', 'dd/mm/yyyy') presentationdatestart, to_date('31/05/2016', 'dd/mm/yyyy') presentationdateend from dual union all
                          select 624 presentationid, 'Wednesday' presentationday, to_date('01/05/2016', 'dd/mm/yyyy') presentationdatestart, to_date('07/06/2016', 'dd/mm/yyyy') presentationdateend from dual union all
                          select 625 presentationid, 'Thursday' presentationday, to_date('01/05/2016', 'dd/mm/yyyy') presentationdatestart, to_date('07/06/2016', 'dd/mm/yyyy') presentationdateend from dual)
    -- end of mimicking your presentation table with data in it. You wouldn't need this subquery as you have the table; see SQL below.
    select presentationid,
           presentationday,
           to_char(next_day(presentationdatestart -1, presentationday) + 7*(level - 1), 'DD-MM-YYYY') list_date
    from   presentation
    connect by prior presentationid = presentationid
               and prior sys_guid() is not null
               and next_day(presentationdatestart -1, presentationday) + 7*(level - 1) <= presentationdateend
    order by next_day(presentationdatestart -1, presentationday) + 7*(level - 1),
             presentationid;
    
    PRESENTATIONID PRESENTATIONDAY LIST_DATE 
    -------------- --------------- ----------
               622 Monday          02-05-2016
               623 Tuesday         03-05-2016
               624 Wednesday       04-05-2016
               625 Thursday        05-05-2016
               622 Monday          09-05-2016
               623 Tuesday         10-05-2016
               624 Wednesday       11-05-2016
               625 Thursday        12-05-2016
               622 Monday          16-05-2016
               623 Tuesday         17-05-2016
               624 Wednesday       18-05-2016
               625 Thursday        19-05-2016
               622 Monday          23-05-2016
               623 Tuesday         24-05-2016
               624 Wednesday       25-05-2016
               625 Thursday        26-05-2016
               622 Monday          30-05-2016
               623 Tuesday         31-05-2016
               624 Wednesday       01-06-2016
               625 Thursday        02-06-2016