按时间间隔按计数分组

时间:2018-12-10 23:59:53

标签: sql oracle

我建立了以下查询:

select CALL_RESULT, val from (
SELECT CALL_RESULT,
  TO_CHAR (
    FROM_TZ (
      CAST (DATE '1970-01-01' + (1/24/60/60) * CALL_TIME AS TIMESTAMP),
      'UTC')
    AT TIME ZONE 'Pacific/Auckland',
  'MM/DD/YYYY HH24:MI:SS') as val 
FROM WI_TABLE_1 
) where val >= '12/10/2018' group by CALL_RESULT, val;

它输出以下数据:

CALL_RESULT    VAL
8              12/10/2018 10:11:49
8              12/10/2018 10:15:56
8              12/10/2018 09:24:02
8              12/10/2018 09:24:14
8              12/10/2018 10:11:25
8              12/10/2018 10:12:01
8              12/10/2018 10:14:24
11             12/10/2018 09:20:47
11             12/10/2018 09:18:12
11             12/10/2018 09:18:30
11             12/10/2018 09:18:45
11             12/10/2018 09:18:46
...            ....

我现在尝试计算不同的CALL_RESULT,但按15分钟的时间间隔分组。 我已经尝试了所有我能想到的,但没有成功。是否有可以帮助我的Oracle向导?

这个主意是:

CALL_RESULT    INTERVAL              COUNT
8              10:00                 3
11             10:00                 1
8              10:15                 3
11             10:30                 0
8              10:30                 3
...            ....

2 个答案:

答案 0 :(得分:0)

如果源数据中存在“间隙”,并且您需要在结果中显示每个间隔(例如,可能需要作图),那么您需要生成一组间隔来覆盖所需的时间段。现在,再次有几种方法可以实现,但是下面是包括Oracle 11g(“递归公共表表达式”)在内的许多数据库的通用方法。此示例生成96个15分钟的时间间隔(足够一天): / p>

with cte (n) as (
    select 0 as n from dual

    union all

    select n + 15 from cte
    where n < (24*60)
    )
select
      dt + n/1440 as dt_from
    , dt + (n+15)/1440 as dt_to
from cte
cross join (select to_date('2018-12-10','yyyy-mm-dd') as dt from dual) 

结果将如下所示(dd.mm.yyyy):

+----+---------------------+---------------------+
|    |       DT_FROM       |        DT_TO        |
+----+---------------------+---------------------+
|  1 | 10.12.2018 00:00:00 | 10.12.2018 00:15:00 |
|  2 | 10.12.2018 00:15:00 | 10.12.2018 00:30:00 |
...
| 95 | 10.12.2018 23:30:00 | 10.12.2018 23:45:00 |
| 96 | 10.12.2018 23:45:00 | 11.12.2018 00:00:00 |
+----+---------------------+---------------------+

还有其他一些Oracle特定的方法可以生成值得研究的connect by level行。

一旦您有必要的时间间隔集,就可以将您的数据加入其中,并进行分组

with cte (n) as (
    select 0 as n from dual

    union all

    select n + 15 from cte
    where n < (24*60)-15
    )
select 
     d.CALL_RESULT, r.dt_from, count(d.val)
from (
    select
          cj.dt + n/1440 as dt_from
        , cj.dt + (n+15)/1440 as dt_to
    from cte
    cross join (select to_date('2018-12-10','yyyy-mm-dd') as dt from dual) cj
    ) r
left join (
        SELECT CALL_RESULT
         , val
        FROM (
         SELECT CALL_RESULT
          , TO_CHAR(FROM_TZ(CAST(DATE '1970-01-01' + (1 / 24 / 60 / 60) * CALL_TIME AS TIMESTAMP), 'UTC') AT TIME ZONE 'Pacific/Auckland', 'MM/DD/YYYY HH24:MI:SS') AS val
         FROM WI_TABLE_1
         )
        WHERE val >= '12/10/2018'
        GROUP BY CALL_RESULT
         , val
    ) d on d.val >= r.dt_from and d.val < r.dt_to
group by 
     d.CALL_RESULT, r.dt_from

答案 1 :(得分:-1)

根据您的第一个查询结果,您将想要做类似的事情

select callresult, count(0)
from table
group by datepart(minute, val) / 15

通过对日期的分钟进行四舍五入的分组,将使您有15分钟的分组,可以对以上数据进行操作