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

时间:2018-05-03 07:38:29

标签: sql oracle timespan

我需要过去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; 

结果:

result set

如何获取过去24小时内每小时的数据?

预期数据:

expected data

记录最近24小时内每小时的计数,从当前日期开始。如果该特定小时内没有记录,则显示0。

3 个答案:

答案 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 日历表

  1. count(t.systemdate)需要计算t.systemdate,因为t.systemdate可能是NULL
  2. connect by创建最近24小时的日历表
  3. on子句TO_CHAR(t.systemdate,'YYYY/MM/DD hh24','nls_language=american')确保dateformat语言相同。
  4. 你可以试试这个。

    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