Как мы можем получить 15-минутный интервал времени - PullRequest
0 голосов
/ 23 октября 2019

Я пытаюсь получить каждые 15 минут данных таким образом, чтобы, если текущее время было 23-10-19 11:11:30, мне нужно было получить данные с 23-10-19 10:30:59на 23-10-19 10:45:59 таким же образом, если время 23-10-19 11:15:30, то мне нужно получить данные с 23-10-19 10:45:59 до 23-10-19 11: 00: 59.

Я пытался забыть 15-минутную задержку, но не так, как хочу. Пожалуйста, предложите мне, как мы можем приблизиться к сценарию

select concat(to_char(current_timestamp - numtodsinterval(30,'MINUTE'),'yyyy-mm-dd hh24:mi'),':59') A, 
concat(to_char(current_timestamp - numtodsinterval(15,'MINUTE'),'yyyy-mm-dd hh24:mi'),':59') B, 
to_char(current_timestamp,'yyyy-mm-dd hh24:mi:ss') C from dual 

ниже - это результат, который я получил.

Ответы [ 3 ]

1 голос
/ 23 октября 2019

Вы можете обрезать до ближайшей минуты ноль секунд, а затем вычесть количество минут, чтобы вернуться к ближайшему 15-минутному интервалу после часа, а затем применить свои смещения:

SELECT TRUNC( current_timestamp, 'MI' )
         - MOD( EXTRACT( MINUTE FROM current_timestamp ), 15 ) * INTERVAL '1' MINUTE
         - INTERVAL '30' MINUTE
         + INTERVAL '59' SECOND AS start_time,
       TRUNC( current_timestamp, 'MI' )
         - MOD( EXTRACT( MINUTE FROM current_timestamp ), 15 ) * INTERVAL '1' MINUTE
         - INTERVAL '15' MINUTE
         + INTERVAL '59' SECOND AS end_time,
       current_timestamp
FROM   DUAL

Выходы:

START_TIME          | END_TIME            | CURRENT_TIMESTAMP            
:------------------ | :------------------ | :----------------------------
2019-10-23 09:00:59 | 2019-10-23 09:15:59 | 2019-10-23 09:42:53.742684000

дБ <> скрипка здесь

0 голосов
/ 23 октября 2019
select :start_date + (1/96)*(level-1) from dual connect by level < :intervals
0 голосов
/ 23 октября 2019

Другое решение:

WITH t AS 
    (SELECT TRUNC(CURRENT_TIMESTAMP , 'hh') + TRUNC(EXTRACT(MINUTE FROM CURRENT_TIMESTAMP ) / 15) * INTERVAL '15' MINUTE - INTERVAL '30' MINUTE AS Base
    FROM dual)
SELECT Base + INTERVAL '59' SECOND AS begin_time,
    Base + INTERVAL '15:59' minute to SECOND AS end_time
FROM t;

Оно основано на моей общей функции Interval:

CREATE OR REPLACE FUNCTION MakeInterval(ts IN TIMESTAMP, roundInterval IN INTERVAL DAY TO SECOND) RETURN TIMESTAMP DETERMINISTIC IS
    denom INTEGER;
BEGIN
    IF roundInterval >= INTERVAL '1' HOUR THEN
        denom := EXTRACT(HOUR FROM roundInterval);
        IF MOD(24, denom) <> 0 THEN
            RAISE VALUE_ERROR;
        END IF;
        RETURN TRUNC(ts) + TRUNC(EXTRACT(HOUR FROM ts) / denom) * denom * INTERVAL '1' HOUR;
    ELSIF roundInterval >= INTERVAL '1' MINUTE THEN
        denom := EXTRACT(MINUTE FROM roundInterval);
        IF MOD(60, denom) <> 0 THEN
            RAISE VALUE_ERROR;
        END IF;
        RETURN TRUNC(ts, 'hh') + TRUNC(EXTRACT(MINUTE FROM ts) / denom) * denom * INTERVAL '1' MINUTE;
    ELSE
        denom := EXTRACT(SECOND FROM roundInterval);                
        IF MOD(60, denom) <> 0 THEN
            RAISE VALUE_ERROR;
        END IF;
        RETURN TRUNC(ts, 'mi') + TRUNC(EXTRACT(SECOND FROM ts) / denom) * denom * INTERVAL '1' SECOND;
    END IF;
END MakeInterval;

Вы бы вызывали его как

SELECT MakeInterval(CURRENT_TIMESTAMP, INTERVAL '15' MINUTE) from dual;

плюс / минус ваши постоянные смещения.

...