Tôi có cột DATE
mà tôi muốn làm tròn đến khoảng 10 phút tiếp theo thấp hơn trong truy vấn (xem ví dụ bên dưới).Vòng tròn đến 10 phút khoảng
Tôi đã thực hiện điều đó bằng cách cắt ngắn giây và sau đó trừ số cuối của phút.
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
Và đây là kết quả:
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: 09:59 01.01.2010 10: 00:00
01.01.2010 10: 10:00 01.01.2010 10: 10:00
01.01.2099 10: 00 : 33 2099/01/01 10: 00:00
trình như mong đợi, nhưng là có một cách tốt hơn?
EDIT:
Tôi đã tò mò về hiệu suất, vì vậy tôi đã làm các xét nghiệm sau đây với 500.000 hàng và (không thực sự) ngày ngẫu nhiên. Tôi sẽ thêm các kết quả như ý kiến cho các giải pháp được cung cấp.
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;
Cách tiếp cận này mất 03.24 s
.
gì về 'CHỌN TRƯỜNG HỢP KHI TO_CHAR (date_col, 'MI') giữa 0 và 10 THEN TO_DATE (TO_CHAR (date_col, 'YYYY') || '-' || TO_CHAR (ngày_col, 'MM') || '-' || TO_CHAR (ngày_col, 'DD') || '' || TO_CHAR (ngày_col, 'HH') || ': 00' , 'YYYY-MM-DD HH: MI') END'? –
@OMG Ngựa: Xin lỗi, nhưng trả về toàn bộ giờ khi '0 <= MI <= 10', nếu không' NULL'. –
Không muốn lộn xộn với phần còn lại của WHEN –