【问题标题】:Arrange the date query result [oracle 11g]整理日期查询结果[oracle 11g]
【发布时间】:2016-05-24 15:04:19
【问题描述】:

这是我根据天数获取两个日期之间所有可能日期的查询。

    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;

这些值是从presentationdaypresentationdatestartpresentationdateend 组成的presentation 表中检索的。

此查询的结果是:

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

我怎样才能将这些值排列成这样的:

    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 

【问题讨论】:

  • 首先使用to_char根据需要更改日期格式。第二个 order by 2, 1 而不是 1,2 按日期排序,然后按 id 排列结果行。
  • 您首先想要的东西现在与您现在想要的不同。让我更新我的答案
  • 我在我的问题中更改了我的查询。但是,我尝试按子句更改我的顺序……结果变得更奇怪了。 2016 年 1 月 6 日星期三是第一行。应该是星期一 02-05-2016

标签: oracle date oracle11g dual-table


【解决方案1】:

我想你就在这之后:

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;

注意请注意我是如何删除您的 trim() 并在格式掩码中将其替换为 fm 的。

附:您可以通过以下方式重写查询以删除连接条件(以及对演示表的额外调用):

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

【讨论】:

  • 非常感谢!但是为什么我必须使用fmDay 并删除trim()
  • 因为 a) 它更容易阅读/维护,但是 b) 它的函数调用更少;它使用 to_char() 的内置功能。这将有助于性能,即使它只是一点点。你知道,它的作用与 trim 的作用相同,同时产生字符串。你没有必须使用它,就像你没有必须使用它的启动马达来启动你的汽车(即颠簸启动),但它很方便.
【解决方案2】:

使用这个:

TO_CHAR(A.PRESENTATIONDATESTART+delta,'DD-MM-YYYY','NLS_CALENDAR=GREGORIAN' ) LIST_DATE

而不是

A.PRESENTATIONDATESTART+delta LIST_DATE

这会格式化您的日期

为您的新挑战更新了答案

select * from (
  select A.presentationID,
       A.PRESENTATIONDAY,


          TO_CHAR(A.PRESENTATIONDATESTART+delta,'DD-MM-YYYY','NLS_CALENDAR=GREGORIAN') LIST_DATE,
    row_number() over (partition by presentationID,PRESENTATIONDATESTART+delta
order by presentationID,PRESENTATIONDATESTART+delta) r
    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 r

【讨论】:

  • 您好,感谢您抽出宝贵时间。这个查询会做什么?我试过了,我得到一个缺少右括号的错误。
  • 对不起,我在答案的末尾忘记了一个 '。使用更新的答案。 TO_CHAR 函数将日期格式化为 char 类型。第一个参数是日期第二个是显示格式第三个是日历类型
  • 谢谢你的格式.. 但我仍然无法按照我想要的方式组织查询结果:)
  • 您可以在使用我的答案后输入您的结果吗?
  • 使用 partition by 进行基于分区的排序
猜你喜欢
  • 1970-01-01
  • 2015-01-30
  • 1970-01-01
  • 2017-02-26
  • 1970-01-01
  • 2021-09-16
  • 2013-08-23
  • 2021-01-08
  • 2011-05-25
相关资源
最近更新 更多