날짜를 10분 간격으로 반올림
나는 있습니다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
그 결과는 다음과 같습니다.
01.01.2010 10:00 01.01.2010 10:00:00
01.01.2010 10:05:00 01.01.2010 10:00:00
01.01.2010 10:09:59 01.01.2010 10:00:00
01.01.2010 10:10 01.01.2010 10:10:00
01.01.2099 10:00:3301.01.2099 10: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;
이 접근 방식은03.24 s
.
select
trunc(sysdate, 'mi')
- numtodsinterval(mod(EXTRACT(minute FROM cast(sysdate as timestamp)), 10), 'minute')
from dual;
아니 심지어는
select
trunc(sysdate, 'mi')
- mod(EXTRACT(minute FROM cast(sysdate as timestamp)), 10) / (24 * 60)
from dual;
저는 일반적으로 데이트 -> 캐릭터 -> 데이트 변환이 필요 없을 때 하는 것을 싫어합니다.숫자를 쓰는 게 낫겠어요.
select trunc((sysdate - trunc(sysdate))*60*24,-1)/(60*24)+trunc(sysdate) from dual;
이렇게 하면 현재 날짜에서 분을 추출하여 10분 간격으로 잘라낸 다음 다시 추가하여 날짜를 다시 지정합니다.물론 sysdate를 원하는 날짜로 바꿀 수 있습니다.그것은 내가 원하는 것보다 훨씬 더 암묵적인 변환을 신뢰하지만 적어도 어떤 NLS 날짜 형식에서도 작동할 것입니다.
반환된 값을 문자열로 사용하고 왼쪽을 마지막 1분 자리까지 하위 문자열로 대체할 수 있습니다.0
당신이 어떤 종류의 지표를 제공하지 않는 한 저는 그것을 정확히 더 잘 말하지 않을 것입니다.
반드시 더 나은 것은 아니지만, 다른 방법:
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) + FLOOR((d-TRUNC(d))*24*6)/(24*6)
FROM test_data
또 다른 방법은,
select my_date - mod( (my_date-trunc(my_date))*24*60, 10)/24/60
from (
select sysdate my_date from dual
);
잘라내기 호출을 제거하기 때문에 더 빠를 수도 있습니다.
select my_date - mod( (my_date-to_date('1970', 'yyyy'))*24*60, 10)/24/60
from (
select sysdate my_date from dual
);
다음 상위 10분 간격을 반환하기 위해 다음 쿼리를 사용했습니다.단순히 할 수 없었기 때문에 유용하게 쓰였으면 좋겠습니다.
trunc(sysdate, 'mi') + mod(EXTRACT(minute FROM cast(sysdate as timestamp)), 10) / (24 * 60)
저는 이것을 했고 그것은 저에게 효과가 있었습니다.
select
case when mod(EXTRACT(minute FROM cast(sysdate as timestamp)),5) between 1 and 4
then trunc(sysdate,'mi')+((5*TRUNC(EXTRACT(minute FROM cast(sysdate as timestamp))/5,
0)+5)-EXTRACT(minute FROM cast(sysdate as timestamp)))/1440
else trunc(sysdate,'mi')
end
from dual
이것은 이 게시물을 기반으로 합니다.
이 문제를 해결하려면 10초, 1분, 10분 등의 낮은 간격으로 훨씬 더 쉽고 빠르게 반올림할 수 있는 방법이 있다고 생각합니다.다음과 같이 SUSTR()을 사용하여 타임스탬프를 문자열로 조작해 보십시오.
SELECT
SUBSTR(datetime(d),1,18)||'0' AS Slot10sec,
SUBSTR(datetime(d),1,17)||'00' AS Slot1min,
SUBSTR(datetime(d),1,15)||'0:00' AS Slot10min,
SUBSTR(datetime(d),1,14)||'00:00' AS Slot1h,
MY_VALUE
FROM MY_TABLE;
언급URL : https://stackoverflow.com/questions/2192424/round-date-to-10-minutes-interval
'programing' 카테고리의 다른 글
Document의 Mongoengine creation_time 특성 (0) | 2023.07.07 |
---|---|
스프링 부트 레스트 - 404 구성 방법 - 리소스를 찾을 수 없음 (0) | 2023.07.07 |
PHP MariaDB PDO 수 중복 값 (0) | 2023.07.07 |
ePub 형식을 읽는 중 (0) | 2023.07.07 |
Oracle에서 선택한 행에서 행 번호를 가져오는 방법 (0) | 2023.07.07 |