轮到日期为10分钟

Pet*_*ang 14 sql oracle date rounding

我有一个DATE列,我希望在查询中舍入到下一个较低的10分钟间隔(参见下面的示例).

我设法通过截断秒数然后减去分钟的最后一位数来实现.

WITH test_data AS (
        SELECT TO_DATE('2010-01-01 10:00:00', 'YYYY-MM-DD HH24:MI:SS') d FROM dual
  UNION SELECT TO_DATE('2010-01-01 10:05:00', 'YYYY-MM-DD HH24:MI:SS') d FROM dual
  UNION SELECT TO_DATE('2010-01-01 10:09:59', 'YYYY-MM-DD HH24:MI:SS') d FROM dual
  UNION SELECT TO_DATE('2010-01-01 10:10:00', 'YYYY-MM-DD HH24:MI:SS') d FROM dual
  UNION SELECT TO_DATE('2099-01-01 10:00:33', 'YYYY-MM-DD HH24:MI:SS') d FROM dual
)
-- #end of test-data
SELECT
  d, TRUNC(d, 'MI') - MOD(TO_CHAR(d, 'MI'), 10) / (24 * 60)
FROM test_data
Run Code Online (Sandbox Code Playgroud)

这是结果:

01.01.2010 10:00:00    01.01.2010 10:00:00
01.01.2010 10:05:00    01.01.2010 10:00:00
01.01.2010 10:9时59    01.01.2010 10:00:00
01.01. 2010 10:10:00    01.01.2010 10:10:00
2099年1月1日10:00:33    2099年1月1日10:00:00

按预期工作,但有更好的方法吗?

编辑:

我对性能很好奇,所以我用500.000行和(不是真的)随机日期进行了以下测试.我将把结果作为注释添加到提供的解决方案中.

DECLARE
  t       TIMESTAMP := SYSTIMESTAMP;
BEGIN
  FOR i IN (
    WITH test_data AS (
      SELECT SYSDATE + ROWNUM / 5000 d FROM dual
      CONNECT BY ROWNUM <= 500000
    )
    SELECT TRUNC(d, 'MI') - MOD(TO_CHAR(d, 'MI'), 10) / (24 * 60)
    FROM test_data
  )
  LOOP
    NULL;
  END LOOP;
  dbms_output.put_line( SYSTIMESTAMP - t );
END;
Run Code Online (Sandbox Code Playgroud)

采取这种方法03.24 s.

小智 11

select
  trunc(sysdate, 'mi')
  - numtodsinterval(mod(EXTRACT(minute FROM cast(sysdate as timestamp)), 10), 'minute')
from dual;
Run Code Online (Sandbox Code Playgroud)

甚至

select
  trunc(sysdate, 'mi')
  - mod(EXTRACT(minute FROM cast(sysdate as timestamp)), 10) / (24 * 60)
from dual;
Run Code Online (Sandbox Code Playgroud)