I have a ticketing system that I am trying to run a report on. I am trying to get the number of tickets touched per user. With this first query:
SELECT * FROM (
SELECT TicketID, UserID, EventDateTime
FROM dcscontact.ticketevents
WHERE EventDateTime BETWEEN '2016-06-22' AND '2016-06-23'
ORDER BY EventDateTime DESC) x
WHERE UserID=80
GROUP BY TicketID;
I am able to list the tickets touched for a particular user, and can count them manually:
TicketID UserID EventDateTime
99168 80 6/22/2016 13:21
99193 80 6/22/2016 7:42
99213 80 6/22/2016 13:02
99214 80 6/22/2016 6:30
99221 80 6/22/2016 6:57
99224 80 6/22/2016 7:48
99226 80 6/22/2016 6:27
99228 80 6/22/2016 8:49
99229 80 6/22/2016 8:53
99232 80 6/22/2016 9:18
99237 80 6/22/2016 13:08
But when I try to drop the WHERE UserID= statement, and try to use it as a subquery like so:
SELECT UserID, COUNT(*) as count FROM (
SELECT * FROM (
SELECT TicketID, UserID, EventDateTime
FROM dcscontact.ticketevents
WHERE EventDateTime BETWEEN '2016-06-22' AND '2016-06-23'
ORDER BY EventDateTime DESC) x
GROUP BY TicketID) y
GROUP BY UserID;
I get incorrect counts:
UserID count
9 2
28 1
31 1
42 1
80 5
95 1
99 6
108 4
116 12
117 26
123 24
As you can see, the count for UserID 80 should have been 11. most of the other results are also incorrect, they seem to all be lower numbers than I am expecting.
Am I doing something wrong with the GROUP BY/COUNT when using it on a subquery? How can I change my query to get the results I want?
Do you just want an aggregation?
SELECT UserID, COUNT(*)
FROM dcscontact.ticketevents
WHERE EventDateTime BETWEEN '2016-06-22' AND '2016-06-23'
GROUP BY UserID;
If the same ticket can appear in the data more than one time for a given user,then COUNT(DISTINCT)
is more appropriate:
SELECT UserID, COUNT(DISTINCT TicketID)
FROM dcscontact.ticketevents
WHERE EventDateTime BETWEEN '2016-06-22' AND '2016-06-23'
GROUP BY UserID;
To get number of tickets touched per user , let's start with a proper query for just that:
SELECT count(*) as N, UserID
FROM dcscontact.ticketevents
WHERE EventDateTime BETWEEN '2016-06-22' AND '2016-06-23'
GROUP BY UserID;
A GROUP BY
clause should always include all the non-aggregate columns mentioned in the SELECT
clause. It doesn't make sense to ask for "the ticket ID and the number of tickets (per user)"!
Also, the SQL standard says ORDER BY
cannot apply to subqueries. Best to think of ORDER BY
as a convenience for viewing the output, not as information to be used in the query.
You also want to know something about the TicketID
and EventDateTime
. You can't ask for "the id of the count of the tickets", but you can get the first and last ticket. Same for time:
SELECT count(*) as N
, min(TicketID) as T1
, max(TicketID) as Tn
, min(EventDateTime) as E1
, max(EventDateTime) as En
, UserID
FROM dcscontact.ticketevents
WHERE EventDateTime BETWEEN '2016-06-22' AND '2016-06-23'
GROUP BY UserID;
Note that the earliest time may not be the time of the smallest TicketID. To get everything about the first ticket for each user, plus the count, join the two sources of information:
select N.N, T.*
from dcscontact.ticketevents as T
join (
SELECT count(*) as N, min(TicketID) as T1, UserID
FROM dcscontact.ticketevents
WHERE EventDateTime BETWEEN '2016-06-22' AND '2016-06-23'
GROUP BY UserID;
) as N
on T.UserID = N.UserID
and T.TicketID = N.TicketID
-- and maybe others, according to the key
order by EventDateTime DESC
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.