Reputation: 17
I have a table in my postgres database, where my system records every 5 seconds the state of a variable. I need to count the number of occurrences that a "value = 1" variable occurred during the hours of a day. That is, during the 24 hours of a day, how many hours did my variable stay with "value = 1".
Based on the attached figure, my select should return "2019-10-31 1" and "2019-11-02 01"
I don't know if I was clear enough. Hope so.
Upvotes: 0
Views: 168
Reputation: 9083
Is this what you are looking for:
select date(DATE_TRUNC('day', dat)) as "Date we checking"
, sum(difference) as "Number of occurrences"
from (
select DATE_TRUNC('hour', read_date) dat
, DATE_TRUNC('hour', LAG(read_date) OVER (ORDER BY id)) prev_date
, extract(hour from DATE_TRUNC('hour', read_date) - DATE_TRUNC('hour', LAG(read_date) OVER (
ORDER BY id))) difference
from system) t
where difference <= 1
and dat between '2019-10-31 09:00:00' and '2019-11-01 09:00:00'
group by DATE_TRUNC('day', dat);
With this line you define the 24 hours you want to check:
and dat between '2019-10-31 09:00:00' and '2019-11-01 09:00:00'
Upvotes: 0
Reputation: 1270391
That is, during the 24 hours of a day, how many hours did my variable stay with "value = 1"
You can use:
select read_date::date,
count(distinct date_trunc('hour', read_date)) filter (where value = 1) as num_hours
from t
group by read_date::date;
Upvotes: 1
Reputation: 74660
If you filter the results to only those where value
= 1, and get the distinct list of read_date
s truncated the nearest hour then it will be a list of all the day-hours where a 1 occurred. If we then cast it to a date so it loses the hour, group by that and count, then you'll get the number of hours in a day where value was 1:
SELECT
d::date,
count(*)
FROM
(
SELECT DISTINCT date_trunc('hour', read_date) as d
FROM table
WHERE value = 1
) x
GROUP BY d::date
If, as the commenter has asked, you only seek hours where the value was 1, we can perhaps do something like:
SELECT
d::date,
count(*)
FROM
(
SELECT date_trunc('hour', read_date) as d
FROM table
GROUP BY date_trunc('hour', read_date)
HAVING MIN(value) = 1 AND MAX(value) = 1
) x
GROUP BY d::date
The inner query produces a list of only those hours where the min and max value
s were 1. Any deviation from 1 will cause one of these to be false
Upvotes: 2