两个日期之间的日期+小时列表

时间:2018-02-10 01:52:14

标签: sql oracle

这给了我MM / DD / YYYY:

SELECT TRUNC (to_date('01/02/2018', 'MM/DD/YYYY') - ROWNUM + 1) dt FROM DUAL CONNECT BY ROWNUM <= ( TO_DATE('01/02/2018', 'mm/dd/yyyy') - to_date('12/31/2017', 'MM/DD/YYYY')) + 1 order by 1

我想要这种格式的输出

12/31 10 PM
12/31 11 PM
01/01 12 AM
01/02 1 AM
...

更新

这提供了一个动态日期范围的时间表(分解为每小时,无论有数据)报告上层管理人员想要查看。但是,由于空间的限制,显示4位数的年份是一种浪费。这不是一个益智游戏。

3 个答案:

答案 0 :(得分:2)

试试这个,

ALTER SESSION SET NLS_DATE_FORMAT = 'MM/DD HH AM';

SELECT to_date('12/31/2017', 'MM/DD/YYYY') + (FLOOR(rownum/24) + (MOD(rownum-1, 24)/24)) dt
 FROM DUAL 
 CONNECT BY rownum <= ((to_date('01/02/2018', 'MM/DD/YYYY')+(1/23)) - to_date('12/31/2017', 'MM/DD/YYYY') + (MOD(rownum, 24)/24)) * 24
ORDER BY 1;

输出:

DT        
-----------
12/31 12 AM
12/31 01 AM
12/31 02 AM
12/31 03 AM
12/31 04 AM
12/31 05 AM
12/31 06 AM
12/31 07 AM
12/31 08 AM
12/31 09 AM
12/31 10 AM
12/31 11 AM
12/31 12 PM
12/31 01 PM
12/31 02 PM
12/31 03 PM
12/31 04 PM
12/31 05 PM
12/31 06 PM
12/31 07 PM
12/31 08 PM
12/31 09 PM
12/31 10 PM
01/01 12 AM
01/01 01 AM
01/01 02 AM
01/01 03 AM
01/01 04 AM
01/01 05 AM
01/01 06 AM
01/01 07 AM
01/01 08 AM
01/01 09 AM
01/01 10 AM
01/01 11 AM
01/01 12 PM
01/01 01 PM
01/01 02 PM
01/01 03 PM
01/01 04 PM
01/01 05 PM
01/01 06 PM
01/01 07 PM
01/01 08 PM
01/01 09 PM
01/01 10 PM
01/01 11 PM
01/02 12 AM
01/02 01 AM
01/02 02 AM
01/02 03 AM
01/02 04 AM
01/02 05 AM
01/02 06 AM
01/02 07 AM
01/02 08 AM
01/02 09 AM
01/02 10 AM
01/02 11 AM
01/02 12 PM
01/02 01 PM
01/02 02 PM
01/02 03 PM
01/02 04 PM
01/02 05 PM
01/02 06 PM
01/02 07 PM
01/02 08 PM
01/02 09 PM
01/02 10 PM
01/02 11 PM

选择了71行

如果要指定开始时间和结束时间,请使用下面的查询,我刚修改了第一个查询的CONNECT BY和ORDER BY子句。

SELECT to_date('12/31/2017 10:00 PM', 'MM/DD/YYYY HH:MI AM') + (FLOOR(rownum/24) + (MOD(rownum-1, 24)/24)) dt
   FROM DUAL 
CONNECT BY rownum <= CEIL(((to_date('01/01/2018 02:00 AM', 'MM/DD/YYYY HH:MI AM') - to_date('12/31/2017 10:00 PM', 'MM/DD/YYYY HH:MI AM')) * 24))+1
  ORDER BY rownum;

输出

DT        
-----------
12/31 10 PM
12/31 11 PM
01/01 12 AM
01/01 01 AM
01/01 02 AM

答案 1 :(得分:1)

只需使用:

   SELECT to_char( trunc(sysdate) - ((ROWNUM-2)/24) - 1 , 'MM/DD HH PM') dt -- "pm" part is case-sensitive. i.e. if "PM" or "pm" are used to get upp[low]er results, respectively.   
     FROM DUAL 
  CONNECT BY ROWNUM <= ( trunc(sysdate) - to_date('12/31/2017', 'MM/DD/YYYY')) + 2 
    ORDER BY ROWNUM DESC;

或将trunc(sysdate)替换为您的日期to_date('&&myDate','MM/DD/YYYY')

    SELECT to_char( to_date('&&myDate','MM/DD/YYYY') - ((ROWNUM-2)/24) - 1 , 'MM/DD HH PM') dt
      FROM DUAL 
   CONNECT BY ROWNUM <= ( to_date('&&myDate','MM/DD/YYYY') - to_date('12/31/2017', 'MM/DD/YYYY')) + 2 
     ORDER BY ROWNUM DESC; -- for your case '&&myDate' is called with 01/02/2018

  DT
---------------------------------
  12/31 10 PM
  12/31 11 PM
  01/01 12 AM
  01/01 01 AM

答案 2 :(得分:0)

最好在数据库之外处理这样的事情,但是如果你需要在那里处理它,Oracle会使用EXTRACT来提取部分日期:

您需要EXTRACT(Month FROM dt)EXTRACT(Day FROM dt)EXTRACT(Hour FROM dt)然后连接结果。小时部分将在24小时内完成,因此您需要使用CASE来处理。像这样的东西,使用你的查询版本作为子查询(我不是oracle专家,但我不认为你的查询实际上返回dateTime,它需要为此):

SELECT EXTRACT(Month FROM dt)||'/'||EXTRACT(Day FROM dt)||' '||
  (CASE WHEN EXTRACT(Hour FROM dt)>12 
    THEN (EXTRACT(Hour FROM dt)- 12)|| ' PM' 
    ELSE EXTRACT(Hour FROM dt)|| ' AM')
FROM [...]