获取过去 24 小时内每小时的记录数

get count of records in every hour in the last 24 hour

我需要过去 24 小时内每小时的记录数,如果当天的任何特定小时内没有记录,我需要我的查询显示 0,我只能获取数小时的数据table.

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。

你可以使用这个:

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;

你需要写最后 24 小时日历table,然后LEFT JOIN日历table 原文 table.

  1. count(t.systemdate) 需要计算 t.systemdate 因为 t.systemdate 可能是 NULL
  2. connect by 创建最近 24 小时日历 table
  3. on 子句 TO_CHAR(t.systemdate,'YYYY/MM/DD hh24','nls_language=american') 确保日期格式语言相同。

你可以试试这个。

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写日历table

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

以下可能是您需要的。当我 运行 它反对 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' 根据日期 t运行 计算目标 table 中的记录数。
然后主查询将它们中的两个外部连接起来,显示子查询中的日期和计数。
我更喜欢在他们自己的 CTE 中查询的两个部分,因为它使实际查询非常明显并且 'clean'.

就您的查询而言,您想要这个;

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