我有一个表,其中包含不定期间隔数天的事务(金额列)和相关的时间戳(valuedatetime列)。我需要构建一个查询,该查询从开始到每天结束的常规时间间隔计算累积总和(例如每5分钟)。我们的想法是创建一个可用于构建每日线图的数据集。 我对此很新,任何帮助都将不胜感激。
答案 0 :(得分:1)
Oracle 11g R2架构设置:
CREATE TABLE table_name ( amount, valuedatetime ) AS
SELECT 1, TIMESTAMP '2017-10-22 23:45:21.234' FROM DUAL UNION ALL
SELECT 2, TIMESTAMP '2017-10-22 23:47:10.000' FROM DUAL UNION ALL
SELECT 3, TIMESTAMP '2017-10-22 23:52:41.123' FROM DUAL UNION ALL
SELECT 4, TIMESTAMP '2017-10-22 23:55:23.456' FROM DUAL UNION ALL
SELECT 5, TIMESTAMP '2017-10-22 23:58:24.789' FROM DUAL UNION ALL
SELECT 6, TIMESTAMP '2017-10-22 23:59:59.999' FROM DUAL UNION ALL
SELECT 7, TIMESTAMP '2017-10-23 00:00:00.000' FROM DUAL UNION ALL
SELECT 8, TIMESTAMP '2017-10-23 00:01:02.234' FROM DUAL UNION ALL
SELECT 9, TIMESTAMP '2017-10-23 00:05:00.000' FROM DUAL UNION ALL
SELECT 10, TIMESTAMP '2017-10-23 00:09:59.999' FROM DUAL;
查询1 :
SELECT SUM( amount ),
--channel_id,
TRUNC( valuedatetime )
+
TRUNC(
(
CAST( valuedatetime AS DATE ) - TRUNC( valuedatetime )
)
* 24 -- Hours per day
* 60 -- Minutes per hour
/ 5 -- group into 5 minute buckets
) * 5 / 60 / 24 AS range_start
FROM table_name
GROUP BY
--channel_id,
TRUNC( valuedatetime ),
TRUNC(
(
CAST( valuedatetime AS DATE ) - TRUNC( valuedatetime )
)
* 24 -- Hours per day
* 60 -- Minutes per hour
/ 5 -- group into 5 minute buckets
)
<强> Results 强>:
| SUM(AMOUNT) | RANGE_START |
|-------------|----------------------|
| 3 | 2017-10-22T23:45:00Z |
| 3 | 2017-10-22T23:50:00Z |
| 15 | 2017-10-23T00:00:00Z |
| 15 | 2017-10-22T23:55:00Z |
| 19 | 2017-10-23T00:05:00Z |
如果您想要包含没有条目的期间:
Oracle 11g R2架构设置:
CREATE TABLE table_name ( amount, valuedatetime ) AS
SELECT 1, TIMESTAMP '2017-10-22 23:45:21.234' FROM DUAL UNION ALL
SELECT 2, TIMESTAMP '2017-10-22 23:47:10.000' FROM DUAL UNION ALL
SELECT 3, TIMESTAMP '2017-10-22 23:52:41.123' FROM DUAL UNION ALL
SELECT 4, TIMESTAMP '2017-10-22 23:55:23.456' FROM DUAL UNION ALL
SELECT 5, TIMESTAMP '2017-10-22 23:58:24.789' FROM DUAL UNION ALL
SELECT 6, TIMESTAMP '2017-10-22 23:59:59.999' FROM DUAL UNION ALL
SELECT 7, TIMESTAMP '2017-10-23 00:00:00.000' FROM DUAL UNION ALL
SELECT 8, TIMESTAMP '2017-10-23 00:01:02.234' FROM DUAL UNION ALL
SELECT 9, TIMESTAMP '2017-10-23 00:15:00.000' FROM DUAL UNION ALL
SELECT 10, TIMESTAMP '2017-10-23 00:19:59.999' FROM DUAL;
查询1 :
WITH ranges ( dt ) AS (
SELECT min_dt + NUMTODSINTERVAL( 5 * ( LEVEL - 1 ), 'MINUTE' )
FROM (
SELECT TRUNC( CAST( MIN( valuedatetime ) AS DATE ) )
+
TRUNC(
( CAST( MIN( valuedatetime ) AS DATE )
- TRUNC( MIN( valuedatetime ) ) )
* 24 * 60 / 5
) * 5 / 60 / 24 AS min_dt,
MAX( valuedatetime ) AS max_dt
FROM table_name
)
CONNECT BY
min_dt + INTERVAL '5' MINUTE * ( LEVEL - 1 ) <= max_dt
)
SELECT COALESCE( SUM( amount ), 0 ) AS total_amount,
--channel_id,
r.dt AS range_start
FROM ranges r
LEFT OUTER JOIN table_name t
ON ( r.dt <= t.valuedatetime
AND t.valuedatetime < r.dt + INTERVAL '5' MINUTE )
GROUP BY
--channel_id,
r.dt
ORDER BY
--channel_id,
r.dt
<强> Results 强>:
| TOTAL_AMOUNT | RANGE_START |
|--------------|----------------------|
| 3 | 2017-10-22T23:45:00Z |
| 3 | 2017-10-22T23:50:00Z |
| 15 | 2017-10-22T23:55:00Z |
| 15 | 2017-10-23T00:00:00Z |
| 0 | 2017-10-23T00:05:00Z |
| 0 | 2017-10-23T00:10:00Z |
| 19 | 2017-10-23T00:15:00Z |