简体   繁体   English

MySQL通过不返回正确的结果进行分组

[英]MySQL count with group by not returning correct result

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: 但是,当我尝试删除WHERE UserID =语句,并尝试将其用作子查询时,如下所示:

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. 如您所见,UserID 80的计数应该为11。其他大多数结果也不正确,它们似乎都比我预期的要少。

Am I doing something wrong with the GROUP BY/COUNT when using it on a subquery? 在子查询上使用GROUP BY / COUNT时,我做错什么了吗? 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: 如果对于一个给定用户,同一票证可以多次出现在数据中,则COUNT(DISTINCT)更合适:

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. GROUP BY子句应始终包括SELECT子句中提到的所有非聚合列。 It doesn't make sense to ask for "the ticket ID and the number of tickets (per user)"! 询问“票证ID和票证数量(每位用户)”是没有意义的!

Also, the SQL standard says ORDER BY cannot apply to subqueries. 另外,SQL标准说ORDER BY不能应用于子查询。 Best to think of ORDER BY as a convenience for viewing the output, not as information to be used in the query. 最好将ORDER BY视为查看输出的便利,而不是查询中使用的信息。

You also want to know something about the TicketID and EventDateTime . 您还想知道一些关于TicketIDEventDateTime 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. 请注意,最早的时间可能不是最小的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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM