I want to get three different average values from one column (value_to_count) inside one table where all of those average values has a different WHERE clause (according to time).
###services#### Table
service_id value_to_count time
----------- ----------------------- ---------
604 2054 04:04:50
604 3444 05:00:15
604 2122 07:12:50
604 2144 09:10:50
604 2001 13:12:53
602 2011 15:00:12
602 2115 17:22:35
602 1411 20:22:12
602 1611 21:04:52
602 2111 23:43:45
I'm using this query at the moment to get the average value on time between 18 and 23:
SELECT
service_id AS service, AVG(value_to_count) AS primetime
FROM services
WHERE HOUR(time) BETWEEN 18 AND 23
GROUP BY service_id
And it gives me this kind of results:
### Result ####
service primetime
----------- --------------
604 2154
602 2444
Now I want to get other average values next to the one I already got. This time I just want to get averages by 'HOUR(time) BETWEEN 06 AND 18' and 'HOUR(time) BETWEEN 23 AND 06' aswell.
This is the form of result I want to get:
### Wanted Result ####
service primetime other_time_interval_1 other_time_interval_2
----------- -------------- ---------------- ------------------
604 2154 2352 1842
602 2444 4122 1224
SQL AVG function is used to find out the average of a field in various records. You can take average of various records set using GROUP BY clause. Following example will take average all the records related to a single person and you will have average typed pages by every person.
If you'd like to calculate the average of numeric values stored in a column, you can do so using the AVG() aggregate function; it takes as its argument the name of the column whose average you want to calculate.
To select multiple values, you can use where clause with OR and IN operator.
The SQL AVG function allows you to find the average value from the specified values. Learn how to use it and see some examples in this article.
This should do it:
SELECT service_id AS service,
AVG(case when HOUR(time) BETWEEN 18 AND 23 then value_to_count else null end) AS primetime,
AVG(case when HOUR(time) BETWEEN 06 AND 18 then value_to_count else null end) AS other_time_interval_1
FROM services
GROUP BY service_id
I'd first define the periods for each piece of data, then worry about grouping and averaging:
;With ServicePeriods as (
SELECT Service_id,value_to_count,
CASE WHEN HOUR(time) between 18 and 22 THEN 1
WHEN HOUR(time) between 06 and 17 THEN 2
ELSE 3 END as period
FROM Services
)
select Service_Id,
AVG(CASE WHEN period=1 THEN value_to_count END) as prime_time,
AVG(CASE WHEN period=2 THEN value_to_count END) as other_time_interval_1,
AVG(CASE WHEN period=3 THEN value_to_count END) as other_time_interval_2
from
ServicePeriods
group by Service_id
(Actually, at first I did it as outputting as 3 separate rows, but now I've pivoted as per your requested results)
Because my first CASE
covers all periods, I don't need to think about "between 23 and 06". Note that I've also adjusted the ranges to avoid double counting.
If you want to explicitly check for HOUR(time) between 23 and 06
(or 05), you can do HOUR(time) >= 23 or HOUR(time) <= 6
(or <
). Note that you want OR
, not AND
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With