Reputation: 395
I have been looking at several different questions related to hourly average queries but I could not find any that addresses the following.
I have a log table that keeps track on how many times a page is accessed by a user:
ID USERID PAGEID SECNO DATE
1 123 120 14 6/08/2013 10:07:29 AM
1 124 438 1 6/08/2013 11:00:01 AM
1 123 211 18 6/09/2013 14:07:59 PM
1 123 120 14 6/10/2013 05:07:18 PM
1 124 312 4 6/10/2013 08:04:32 PM
1 128 81 54 6/11/2013 07:02:15 AM
and I am trying to get two different queries. One that looks like this:
HOURLY Count Average
12am 0 0
1am 0 0
2am 0 0
3am 0 0
4am 0 0
5am 1 0
6am 0 0
7am 1 0
8am 0 0
9am 0 0
10am 1 0
11am 1 0
12pm 0 0
1pm 0 0
2pm 1 0
3pm 0 0
4pm 0 0
5pm 1 0
6pm 0 0
7pm 0 0
8pm 1 0
9pm 0 0
10pm 0 0
11pm 0 0
The second query like this:
DAY PERCENTAGE
Monday 10%
Tuesday 16%
Wednesday 14%
Thursday 22%
Friday 21%
Saturday 14%
Sunday 3%
**Please notice that the average value is just a sample
So far for the first query I have something like this:
SELECT
HOUR(date) AS hourly,
Count(*)
FROM
logs
GROUP BY
hourly
I tried adding AVG() after Count() but did not work.
My log table does not have data for every single hour but i still need to display all the hours on my report. if hour empty, then value 0. Any ideas how could I achieve that?
Upvotes: 1
Views: 1917
Reputation: 2235
SQL has no way to "create" an hour out of nothing. So the simple trick is to have a table numbers (number int)
with the numbers you need (may be 1- 31 to be ready for month, or 1-366 for year). That table you can left join with your data in the kind of
select n.number as hour, count(*) as cnt
from numbers as n
left join logtable as l
on hour(l.date) = n.number
group by n.number
You could "simulate" it without a table, but there are several occasions where that table is helpful.
Upvotes: 2
Reputation: 8090
Try this for the first query:
SELECT
h.hour,
IFNULL(tmp.the_count,0),
IFNULL(tmp.the_avg,0)
FROM
hourly h
LEFT JOIN (
SELECT
hourly,
SUM(visits) the_count,
SUM(visits)/COUNT(DISTINCT userid) as the_avg
FROM (
SELECT
HOUR(date) AS hourly,
COUNT(*) as visits,
userid
FROM
logs
GROUP BY
hourly,
userid
) as tmp
GROUP BY
hourly
) as tmp
ON tmp.hourly = h.hour
Try this for the second query:
SELECT
theday,
IFNULL(percentage,0) as percentage
FROM (
SELECT DATE_FORMAT('2013-06-16','%W') as theday UNION
SELECT DATE_FORMAT('2013-06-16' - INTERVAL 1 DAY,'%W') as theday UNION
SELECT DATE_FORMAT('2013-06-16' - INTERVAL 2 DAY,'%W') as theday UNION
SELECT DATE_FORMAT('2013-06-16' - INTERVAL 3 DAY,'%W') as theday UNION
SELECT DATE_FORMAT('2013-06-16' - INTERVAL 4 DAY,'%W') as theday UNION
SELECT DATE_FORMAT('2013-06-16' - INTERVAL 5 DAY,'%W') as theday UNION
SELECT DATE_FORMAT('2013-06-16' - INTERVAL 6 DAY,'%W') as theday
) as weekt
LEFT JOIN (
SELECT
DATE_FORMAT(date,'%W') AS daily,
(COUNT(*)/(SELECT COUNT(*) FROM logs))/100 as percentage
FROM
logs
WHERE
date >= '2013-06-10'
AND date <= '2013-06-16'
GROUP BY
daily
) as logdata
ON logdata.daily = weekt.theday
Upvotes: 4