计算记录并按小时对它们进行分组

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了计算记录并按小时对它们进行分组相关的知识,希望对你有一定的参考价值。

我正在尝试计算表格中的记录并按小时对它们进行分组,我的查询得到结果,但我希望它每小时返回一次,即使没有记录。

我目前的疑问是,

SELECT nvl(count(*),0) AS transactioncount, trunc(date_modified, 'HH') as TRANSACTIONDATE
FROM TABLE 
WHERE date_modified between to_date('23-JAN-19 07:00:00','dd-MON-yy hh24:mi:ss') and to_date('24-Jan-19 06:59:59','dd-MON-yy hh24:mi:ss') 
group by trunc(date_modified, 'HH');

这会返回这样的结果,

TRANSACTIONCOUNT    |    TRANSACTIONDATE
      43            |   23-Jan-19 07:00:00
      47            |   23-Jan-19 08:00:00
      156           |   23-Jan-19 14:00:00
      558           |   23-Jan-19 15:00:00

我想要的是它在我的两个日期之间每小时返回一次,所以,

TRANSACTIONCOUNT    |    TRANSACTIONDATE
      43            |   23-Jan-19 07:00:00
      47            |   23-Jan-19 08:00:00
      0             |   23-Jan-19 09:00:00
      0             |   23-Jan-19 10:00:00
      0             |   23-Jan-19 11:00:00
      0             |   23-Jan-19 12:00:00
      0             |   23-Jan-19 13:00:00
      156           |   23-Jan-19 14:00:00
      558           |   23-Jan-19 15:00:00
  --......
      0             |   24-Jan-19 00:00:00
      0             |   24-Jan-19 01:00:00
      0             |   24-Jan-19 02:00:00
  --and so on
答案

您可以考虑使用以下CONNECT BY level逻辑:

SELECT sum(transactioncount) as transactioncount, transactiondate 
  FROM
  (
   with "TABLE"(date_modified) as
   (
     SELECT timestamp'2019-01-23 08:00:00' FROM dual union all
     SELECT timestamp'2019-01-23 08:30:00' FROM dual union all
     SELECT timestamp'2019-01-23 09:00:00' FROM dual union all
     SELECT timestamp'2019-01-24 05:01:00' FROM dual   
   )   
  SELECT nvl(count(*),0) AS transactioncount, trunc(date_modified, 'hh24') as transactiondate
    FROM "TABLE" t 
   GROUP BY trunc(date_modified, 'HH24')
  UNION ALL
  SELECT 0, timestamp'2019-01-23 07:00:00' + ( level - 1 )/24
    FROM dual    
 CONNECT BY level <=  24 * extract( day  from 
                            timestamp'2019-01-24 06:59:59'-
                            timestamp'2019-01-23 07:00:00') +
                           extract( hour from 
                            timestamp'2019-01-24 06:59:59'-
                            timestamp'2019-01-23 07:00:00') + 1      
)    
 GROUP BY transactiondate
 ORDER BY transactiondate

Rextester Demo

另一答案

要填补交易时间的漏洞,您需要先创建一个完整的小时表。

你可以用Recursive Subquery Factoring来做

WITH hour_table(TRANSACTIONDATE) AS (
   SELECT to_date('23-JAN-19 07:00:00','dd-MON-yy hh24:mi:ss') /* init hour here */
     FROM DUAL
  UNION ALL
   SELECT TRANSACTIONDATE + 1/24
     FROM hour_table
    WHERE TRANSACTIONDATE + 1/24 < to_date('24-JAN-19 06:59:59','dd-MON-yy hh24:mi:ss') /* limit here */
)
select * from hour_table;

TRANSACTIONDATE   
-------------------
23.01.2019 07:00:00 
23.01.2019 08:00:00 
... 
24.01.2019 05:00:00 
24.01.2019 06:00:00 

请注意,您在此查询中使用开始日期和结束日期,开始日期必须精确到一小时。

下一步就是将此小时表外连接到您的聚合,并使用NVL设置缺少小时的默认值。

with hour_table(TRANSACTIONDATE) AS (
   SELECT to_date('23-JAN-19 07:00:00','dd-MON-yy hh24:mi:ss') /* init hour here */
     FROM DUAL
  UNION ALL
   SELECT TRANSACTIONDATE + 1/24
     FROM hour_table
    WHERE TRANSACTIONDATE + 1/24 < to_date('24-JAN-19 06:59:59','dd-MON-yy hh24:mi:ss') /* limit */
),
agg as (   
   SELECT nvl(count(*),0) AS transactioncount, trunc(date_modified, 'HH') as TRANSACTIONDATE
   FROM "TABLE" 
   WHERE date_modified between to_date('23-JAN-19 07:00:00','dd-MON-yy hh24:mi:ss') and to_date('24-Jan-19 06:59:59','dd-MON-yy hh24:mi:ss') 
   group by trunc(date_modified, 'HH')
)
select t.TRANSACTIONDATE, nvl(transactioncount,0) transactioncount
from hour_table t
left outer join agg a
on t.TRANSACTIONDATE = a.TRANSACTIONDATE
order by 1;

以上是关于计算记录并按小时对它们进行分组的主要内容,如果未能解决你的问题,请参考以下文章

python 解析url并按路径对它们进行分组

mysql计算行并按月分组[重复]

Mysql:每月统计记录(包括零)

MySQL按天计数和分组

计算 20 秒间隔内的平均值并按另一列分组

创建单词列表并按索引分组