views:

46

answers:

2

I have a table in an Oracle database that contains actions performed by users in one of our systems. It's used for statistical analysis and I need to display the number of actions performed for a given date, grouped by hour of the day.

I have a query that does that fine, however, it does not display the hours of the day that contain no actions (obviously because there are no records to display for that hour).

For example, the query:

SELECT TO_CHAR(event_date, 'HH24') AS during_hour,
  COUNT(*)
FROM user_activity
WHERE event_date BETWEEN to_date('15-JUN-2010 14:00:00', 'DD-MON-YYYY HH24:MI:SS') 
    AND to_date('16-JUN-2010 13:59:59', 'DD-MON-YYYY HH24:MI:SS')
AND event = 'user.login'
GROUP BY TO_CHAR(event_date, 'HH24')
ORDER BY during_hour;

(Pay no attention to the odd start and end dates, they are like this because they're in GMT and I'm GMT+10 - but that's a separate issue, unless it affects the ability to answer this question)

This produces a result set of:

DURING_HOUR            COUNT(*)               
---------------------- ---------------------- 
00                     12                     
01                     30                     
02                     18                     
03                     20                     
04                     12                     
05                     24                     
06                     20                     
07                     4                      
23                     8                      

9 rows selected

How can I ammend this query to display the hours of the day that contain 0 events?

I've searched Stack Overflow, and found some similar questions, but not that answer my specific issue.

Your assistance is appreciated.

+3  A: 

One option would be to create a separate table with 24 rows: 00 --> 23.

Then outer join against it.

cagcowboy
+6  A: 
SELECT h.hrs, NVL(Quantity, 0) Quantity
FROM (SELECT TRIM(to_char(LEVEL - 1, '00')) hrs
       FROM dual
       CONNECT BY LEVEL < 25) h
LEFT JOIN (SELECT TO_CHAR(event_date, 'HH24') AS during_hour,
                  COUNT(*) Quantity
           FROM user_activity u
           WHERE event_date BETWEEN
                 to_date('15-JUN-2010 14:00:00', 'DD-MON-YYYY HH24:MI:SS') AND
                 to_date('16-JUN-2010 13:59:59', 'DD-MON-YYYY HH24:MI:SS')
           AND event = 'user.login'
           GROUP BY TO_CHAR(event_date, 'HH24')) t
ON (h.hrs = t.during_hour)
ORDER BY h.hrs;
Michael Pakhantsov
Thanks Michael, I tried this query out, but it's giving an oracle error: ORA-00907: missing right parenthesis, Error at Line: 6 Column: 72.
Cyntech
@Cyntech, I corrected query.
Michael Pakhantsov
Thanks Michael!
Cyntech
@Cyntech, so you may accept my answer :)
Michael Pakhantsov