Group date periods

3

I need to do a query that returns all records grouped in certain periods. The table contains a date type and should produce output similar to this:

   | Hora  | Quantidade |
-------------------------
01 | 08:00 | 30         |
02 | 08:05 | 28         |
03 | 08:10 | 32         |
04 | 08:15 | 53         |

That is:

In line 1 were found 30 records with the date column between 08:00:00 and 08:04:59, line 2 were found 28 records with the date column between 08:05:00 and 08:09:59 , so on.

Is there any way to group the date by period as described in the table?

PS: The DBMS is Oracle.

    
asked by anonymous 10.11.2016 / 13:38

3 answers

1

One efficient way to do this is to get the values per column instead of rows, since you already know the desired number of hours in advance. This way the query is fast, since it will be passed once in each record only. Otherwise (per line) you would need to do a subquery and return the lines by filtering each time interval separately, getting much slower and much longer your select.

select 
 sum(case when to_char(campodata, 'hh:mm:ss') between '08:00:00' and '08:04:59' then 1 else 0 end) as "08:00"
,sum(case when to_char(campodata, 'hh:mm:ss') between '08:05:00' and '08:09:59' then 1 else 0 end) as "08:05"
,sum(case when to_char(campodata, 'hh:mm:ss') between '08:10:00' and '08:14:59' then 1 else 0 end) as "08:10"
,sum(case when to_char(campodata, 'hh:mm:ss') between '08:15:00' and '08:19:59' then 1 else 0 end) as "08:15"
from tabela
    
09.12.2016 / 05:10
0
select Sum(campodata), compodata from tabela group by campodata;

sum will give you the sum and group by will group

    
10.11.2016 / 13:44
0

To group by a range, truncate the date in the unit of that interval (minute, in your case), divide by the total of a day and add with the date and time:

(trunc(current_date, 'hh')+trunc(to_char(current_date,'mi')/5)*5/1440)

In this SQL Fiddle I created a table with some timestamps for testing, in the column named d :

> select * from datas;

|                     D |
|-----------------------|
| 2017-10-01 08:00:00.0 |
| 2017-10-01 08:01:00.0 |
| 2017-10-01 08:03:00.0 |
| 2017-10-01 08:07:00.0 |
| 2017-10-01 08:08:00.0 |
| 2017-10-01 08:09:59.0 |
| 2017-10-01 08:11:00.0 |
| 2017-10-01 08:11:15.0 |
| 2017-10-01 08:13:00.0 |
| 2017-10-01 08:17:00.0 |

For this table I apply the above method both to get the five-minute period and to the GROUP BY clause and to a window, in order to get the record numerator that appears in your question:

select 
  row_number() over (order by (trunc(d, 'hh')+trunc(to_char(d,'mi')/5)*5/1440)) as " ", 
  to_char((trunc(d, 'hh')+trunc(to_char(d,'mi')/5)*5/1440), 'HH24:MI') as "Hora",
  count(*) as "Quantidade"
from datas
group by (trunc(d, 'hh')+trunc(to_char(d,'mi')/5)*5/1440);

|   |  Hora | Quantidade |
|---|-------|------------|
| 1 | 08:00 |          3 |
| 2 | 08:05 |          3 |
| 3 | 08:10 |          3 |
| 4 | 08:15 |          1 |
    
09.10.2017 / 07:38