我需要过去24小时内每小时的记录数量,如果当天任何特定小时内没有记录,我需要显示0,我只能获得数小时的数据在表格中。
SELECT TRUNC(systemdate,'HH24') + (trunc(to_char(systemdate,'mi')/10)*10)/24/60 AS date1,
count(*) AS txncount
FROM transactionlog
GROUP BY TRUNC(systemdate,'HH24') + (trunc(to_char(systemdate,'mi')/10)*10)/24/60 order by date1 desc;
结果:
如何获取过去24小时内每小时的数据?
预期数据:
记录最近24小时内每小时的计数,从当前日期开始。如果该特定小时内没有记录,则显示0。
答案 0 :(得分:1)
你可以用这个:
WITH transactionlog AS
(
SELECT TO_DATE('03/05/2018 01:12','dd/mm/yyyy hh24:mi') AS systemdate, 60 AS value
FROM dual UNION ALL
SELECT TO_DATE('03/05/2018 01:32','dd/mm/yyyy hh24:mi'), 35 FROM dual UNION ALL
SELECT TO_DATE('03/05/2018 09:44','dd/mm/yyyy hh24:mi'), 31 FROM dual UNION ALL
SELECT TO_DATE('03/05/2018 08:56','dd/mm/yyyy hh24:mi'), 24 FROM dual UNION ALL
SELECT TO_DATE('03/05/2018 08:02','dd/mm/yyyy hh24:mi'), 98 FROM dual
)
, time_range AS
(
SELECT TRUNC(sysdate, 'hh24') - 23/24 + (ROWNUM - 1) / 24 AS time1
FROM all_objects
WHERE ROWNUM <= 24
)
SELECT TO_CHAR(r.time1, 'mm/dd/yyyy hh:mi AM') AS date1,
COUNT(t.systemdate) AS txncount
FROM time_range r
LEFT JOIN transactionlog t
ON r.time1 = TRUNC(t.systemdate, 'hh24') --+ 1/24
GROUP BY r.time1
ORDER BY r.time1;
如果01:12 AM表示结果中的02:00 AM,则省略注释码。
参考:Generating Dates between two date ranges_AskTOM
编辑:对于OP,你只需要这个:
WITH time_range AS
(
SELECT TRUNC(sysdate, 'hh24') - 23/24 + (ROWNUM - 1) / 24 AS time1
FROM all_objects
WHERE ROWNUM <= 24
)
SELECT TO_CHAR(r.time1, 'mm/dd/yyyy hh:mi AM') AS date1,
COUNT(t.systemdate) AS txncount
FROM time_range r
LEFT JOIN transactionlog t
ON r.time1 = TRUNC(t.systemdate, 'hh24') --+ 1/24
GROUP BY r.time1
ORDER BY r.time1;
答案 1 :(得分:1)
以下可能是您所需要的。当我针对all_objects视图运行它时似乎有效。
WITH date_range
AS (SELECT TRUNC(sysdate - (rownum/24),'HH24') as the_hour
FROM dual
CONNECT BY ROWNUM <= 1000),
the_data
AS (SELECT TRUNC(created, 'HH24') as cr_ddl, count(*) as num_obj
FROM all_objects
GROUP BY TRUNC(created, 'HH24'))
SELECT TO_CHAR(dr.the_hour,'DD/MM/YYYY HH:MI AM'), NVL(num_obj,0)
FROM date_range dr LEFT OUTER JOIN the_data ao
ON ao.cr_ddl = dr.the_hour
ORDER BY dr.the_hour DESC
'date_range'生成过去24小时内每小时的记录
'the_data'根据截断到小时的日期计算目标表中的记录数。
主查询然后外部加入其中两个显示子查询中的日期和计数
我更喜欢在他们自己的CTE中查询的两个部分,因为它使得实际查询非常明显并且“干净”。
就您的查询而言,您需要这个;
WITH date_range
AS (SELECT TRUNC(sysdate - (rownum/24),'HH24') as the_hour
FROM dual
CONNECT BY ROWNUM <= 24),
the_data
AS (SELECT TRUNC(systemdate, 'HH24') as log_date, count(*) as num_obj
FROM transactionlog
GROUP BY TRUNC(systemdate, 'HH24'))
SELECT TO_CHAR(dr.the_hour,'DD/MM/YYYY HH:MI AM'), NVL(trans_log.num_obj,0)
FROM date_range dr LEFT OUTER JOIN the_data trans_log
ON trans_log.log_date = dr.the_hour
ORDER BY dr.the_hour DESC
答案 2 :(得分:0)
您需要按原始表格编写最近24小时日历表,然后LEFT JOIN
日历表。
count(t.systemdate)
需要计算t.systemdate
,因为t.systemdate
可能是NULL
connect by
创建最近24小时的日历表on
子句TO_CHAR(t.systemdate,'YYYY/MM/DD hh24','nls_language=american')
确保dateformat语言相同。你可以试试这个。
WITH Hours as
(
select sysdate + (level/24) dates
from dual
connect by level <= 24
)
SELECT TO_CHAR(h.dates,'YYYY-MM-DD HH24') AS dateHour, count(t.systemdate) AS totlecount
FROM Hours h
LEFT JOIN transactionlog t
on TO_CHAR(t.systemdate,'YYYY/MM/DD hh24','nls_language=american')
= TO_CHAR(h.dates,'YYYY/MM/DD hh24','nls_language=american')
GROUP BY h.dates
ORDER BY h.dates
sqlfiddle:http://sqlfiddle.com/#!4/73db7/2
CTE递归版本
您还可以使用 CTE Recursive 来编写日历表
WITH Hours(dates,i) as
(
SELECT sysdate,1
FROM DUAL
UNION ALL
SELECT sysdate + (i/24),i+1
FROM Hours
WHERE i<24
)
SELECT TO_CHAR(h.dates,'YYYY-MM-DD HH24') AS dateHour, count(t.systemdate) AS totlecount
FROM Hours h
LEFT JOIN transactionlog t
on TO_CHAR(t.systemdate,'YYYY/MM/DD hh24','nls_language=american')
= TO_CHAR(h.dates,'YYYY/MM/DD hh24','nls_language=american')
GROUP BY h.dates
ORDER BY h.dates
sqlfiddle:http://sqlfiddle.com/#!4/73db7/7