如何在sql中转换日期格式

时间:2014-08-06 11:12:48

标签: sql oracle

如果我有这样的日期/时间

8/5/2014 12:00:01 AM
8/5/2014 12:00:16 AM
8/5/2014 12:00:18 AM
8/5/2014 12:17:18 AM
8/5/2014 12:19:18 AM

我想要这些日期/时间

  • 如果分钟小于15且大于00,我希望分钟的时间为00
  • 如果分钟小于30且大于15,我希望分钟为15
  • 如果分钟小于45且大于30,我希望分钟为30
  • 如果分钟小于00且大于45,我希望分钟为45

    8/5/2014 12:00:00 AM
    ...
    ...
    8/5/2014 12:15:00AM
    ... 
    ...
    8/5/2014 12:30:00AM
    ... 
    ...
    8/5/2014 12:45:00AM
    

我需要为我的报告做到这一点 我怎样才能在oracle中应用这些

4 个答案:

答案 0 :(得分:1)

这是一种方法。提取日期,然后按小时和分钟添加您想要的内容:

select trunc(dt) + extract(hour from dt) / 24.0 +
       (trunc(extract(minute from dt) / 15) * 15) / (24.0 * 60);

这使用了+日期添加天数的事实。这三个术语是午夜的原始日期,转换为天数的小时数(因此为/ 24),第三个是分钟数,适当地为四舍五入。

答案 1 :(得分:1)

这是另一种方法,它实际上是Gordon Linoff方法的一种变体:

trunc(dt, 'HH24') + ((15/1440) * (floor(to_number(to_char(dt, 'MI'))/15)))

trunc(dt, 'HH24')为您提供截断为小时精度的值,因此您的样本始终是午夜。然后floor(to_number(to_char(dt, 'MI'))/15)为您提供由分钟值表示的完整15分钟时段的数量;您的数据是零或1.正如戈登提到的那样,当您将数值添加到日期时,它被视为一天中的一小部分,因此需要乘以“15分钟” #39; (一千四分之十五)。

with t as (
  select to_date('8/5/2014 12:00:01 AM') as dt from dual
  union all select to_date('8/5/2014 12:00:16 AM') as dt from dual
  union all select to_date('8/5/2014 12:00:18 AM') as dt from dual
  union all select to_date('8/5/2014 12:17:18 AM') as dt from dual
  union all select to_date('8/5/2014 12:19:18 AM') as dt from dual
  union all select to_date('8/5/2014 12:37:37 AM') as dt from dual
  union all select to_date('8/5/2014 12:51:51 AM') as dt from dual
)
select dt, trunc(dt, 'HH24')
    + ((15/1440) * (floor(to_number(to_char(dt, 'MI'))/15))) as new_dt
from t;

DT                     NEW_DT               
---------------------- ----------------------
08/05/2014 12:00:01 AM 08/05/2014 12:00:00 AM 
08/05/2014 12:00:16 AM 08/05/2014 12:00:00 AM 
08/05/2014 12:00:18 AM 08/05/2014 12:00:00 AM 
08/05/2014 12:17:18 AM 08/05/2014 12:15:00 AM 
08/05/2014 12:19:18 AM 08/05/2014 12:15:00 AM 
08/05/2014 12:37:37 AM 08/05/2014 12:30:00 AM 
08/05/2014 12:51:51 AM 08/05/2014 12:45:00 AM 

答案 2 :(得分:1)

要添加另一种方法,这看起来像函数NUMTODSINTERVAL()可能有用的情况 - 它使得发生的事情稍微明显一点:

select trunc(dt) 
       + numtodsinterval(trunc(to_char(dt, 'sssss') / 900) * 15, 'MINUTE')
  from ...

TRUNC()将日期截断到当天的开头。 format model sssss计算自午夜以来的秒数。从午夜开始的完整的四分之一小时数是秒数除以900(因为当天有900个季度小时)。这将被删除以删除任何部分完成的四分之一小时,乘以15得到分钟数(一刻钟内有15分钟)。最后,将其转换为INTERVAL DAY TO SECOND并添加到原始日期。

SQL> alter session set nls_date_format = 'dd/mm/yyyy hh24:mi:ss';

Session altered.

SQL> with t as (
  2   select to_date('05/08/2014 12:00:01') as dt from dual union all
  3   select to_date('05/08/2014 12:00:16') as dt from dual union all
  4   select to_date('05/08/2014 12:00:18') as dt from dual union all
  5   select to_date('05/08/2014 12:17:18') as dt from dual union all
  6   select to_date('05/08/2014 12:19:18') as dt from dual union all
  7   select to_date('05/08/2014 12:37:37') as dt from dual union all
  8   select to_date('05/08/2014 12:51:51') as dt from dual
  9  )
 10  select trunc(dt)
 11         + numtodsinterval(trunc(to_char(dt, 'sssss') / 900) * 15, 'MINUTE')
 12    from t
 13         ;

TRUNC(DT)+NUMTODSIN
-------------------
05/08/2014 12:00:00
05/08/2014 12:00:00
05/08/2014 12:00:00
05/08/2014 12:15:00
05/08/2014 12:15:00
05/08/2014 12:30:00
05/08/2014 12:45:00

7 rows selected.

我已经明确设置了我的NLS_DATE_FORMAT,因此我可以依赖TO_DATE()中的隐式转换,以便它可以在不滚动的情况下适合页面。 建议正常使用隐式转换。

答案 3 :(得分:0)

以下是ORACLE与实际日期的示例:

select trunc(sysdate,'HH')+trunc(to_number(to_char(sysdate,'MI'))/15)*15/24/60
from dual;