Reputation: 4780
My table is like:
+---------+---------+------------+-----------------------+---------------------+
| visitId | userId | locationId | comments | time |
+---------+---------+------------+-----------------------+---------------------+
| 1 | 3 | 12 | It's a good day here! | 2012-12-12 11:50:12 |
+---------+---------+------------+-----------------------+---------------------+
| 2 | 3 | 23 | very beautiful | 2012-12-12 12:50:12 |
+---------+---------+------------+-----------------------+---------------------+
| 3 | 3 | 52 | nice | 2012-12-12 13:50:12 |
+---------+---------+------------+-----------------------+---------------------+
which records visitors' trajectory and some comments on the places visited.
I want to count the numbers of visitors that visit a specific place (say id=3227) from 0:00 to 23:59, over some interval (ie. 30mins)
I was trying to do this by :
SELECT COUNT(*) FROM visits
GROUP BY HOUR(time), SIGN( MINUTE(time) - 30 )// if they are in the same interval this will yield the same result
WHERE locationId=3227
The problem is that if there is no record that falls in some interval, this will NOT return that interval with count 0. For example, there are no visitors visiting the location from 02:00 to 03:00, this will not give me the intervals of 02:00-02:29 and 02:30-2:59.
I want a result with an exact size of 48 (one for every half hour), how can I do this?
Upvotes: 0
Views: 227
Reputation: 1270061
You have to create a table with the 48 rows that you want and use left outer join:
select n.hr, n.hr, coalesce(v.cnt, 0) as cnt
from (select 0 as hr, -1 as sign union all
select 0, 1 union all
select 1, -1 union all
select 1, 1 union all
. . .
select 23, -1 union all
select 23, 1 union all
) left outer join
(SELECT HOUR(time) as hr, SIGN( MINUTE(time) - 30 ) as sign, COUNT(*) as cnt
FROM visits
WHERE locationId=3227
GROUP BY HOUR(time), SIGN( MINUTE(time) - 30 )
) v
on n.hr = v.hr and n.sign = v.sign
order by n.hr, n.hr
Upvotes: 2