在SQL中将日期字段舍入到下一个半小时

时间:2012-03-26 18:29:30

标签: sql oracle

在SQL中,我有一个DATE变量,我希望将其舍入到下一个可用的半小时(即xx:30)。请注意,这不应该只是最近的半小时。

以下是一些例子:

Time                   Expected outcome
2012-03-26 11:25 AM    2012-03-26 11:30 AM
2012-03-26 11:45 AM    2012-03-26 12:30 PM

有没有办法在SQL中执行此操作?

6 个答案:

答案 0 :(得分:10)

这有点令人费解,但有点像

SELECT round( (date_col - trunc(date_col)) * 48 )/ 48 +
         trunc( date_col )
  FROM dual

应该有效。

SQL> ed
Wrote file afiedt.buf

  1  select round((sysdate - trunc(sysdate)) * 48)/48 + trunc(sysdate),
  2         sysdate
  3*   from dual
SQL> /

ROUND((SYSDATE-TRUNC SYSDATE
-------------------- --------------------
26-mar-2012 14:30:00 26-mar-2012 14:35:30
  • TRUNC(date_col)截断时间到午夜。
  • date_col - trunc(date_col)返回自午夜起已经过的一天中的一小部分。
  • 乘以48可获得半小时增量的数量
  • 舍入给你最近的半小时
  • 然后除以48会给你一天的一小部分,可以添加回trunc(date_col)

答案 1 :(得分:5)

给贾斯汀的原创性答案+1。

如果你想要一个更迂腐(或者,更容易理解或维护)的方法,

select case when to_number(to_char(sysdate,'mi')) > 30
       then trunc(sysdate,'mi') + ((60 - to_number(to_char(sysdate,'mi')) +30)/1440)
       else trunc(sysdate,'mi') + (30 - to_number(to_char(sysdate,'mi')))/1440 end
from dual

我只是把它扔在那里,因为如果你需要做一些类似于其他数字的事情,例如像一小时过去45分钟,这可能是一种更具适应性的方法。你只需用45s取代三个30s就可以了。

但是,对于表演,对于你的确切问题 - 贾斯汀是一个真正的赢家。

答案 2 :(得分:3)

以下是贾斯汀答案的一点调整,我认为这会给你想要的结果:

WITH thedate AS (SELECT trunc(SYSDATE)+6.5/48 thedate FROM dual)
select round((thedate - trunc(thedate)) * 24 - 1/(24*3600))/24 + trunc(thedate)+1/48,
          theDATE
     from thedate;

基本上,这一轮到最近的小时(减去一秒以防止在半小时后完成的四舍五入)然后增加半小时。

答案 3 :(得分:3)

我的代码使用ROUND函数来舍入到最近的小时,然后再添加半小时

WITH thedate AS
     (SELECT TO_DATE ('2012-03-26 11:20 AM', 'YYYY-MM-DD HH:MI AM') mydate
        FROM DUAL)
SELECT mydate,
       TO_CHAR (ROUND (mydate, 'HH') + 1 / 48,
                'YYYY-MM-DD HH:MI AM'
               ) "Rounded Date"
  FROM thedate;

希望有所帮助

答案 4 :(得分:2)

要获得下一个半小时,请通过将ROUND更改为CEIL来修改Justin Cave的解决方案:

SELECT CEIL( (date_col - trunc(date_col)) * 48 )/ 48 +
         trunc( date_col )
  FROM dual

ROUND 转到最近(向上或向下), CEIL 转到 next (始终向上)。 FLOOR 会转到上一个(总是关闭)。

回答Michael Broughton关于维护性的观点:

48是一天中“半小时”的数量。要更改期间,请将以下两个实例替换为:

60/x * 24

其中x是您想要的时段内的分钟数。

E.g。每10分钟=(60/10)* 24 = 144。

希望这有帮助!

答案 5 :(得分:0)

简化(我希望)......

select 
  case
    when to_number(to_char(sysdate,'mi')) <= 30
      then trunc(sysdate,'hh24') + 30/1440
      else trunc(sysdate,'hh24') + 1/24
  end
from dual;