MySQL 通过不返回正确结果与组一起计数
MySQL count with group by not returning correct result
我有一个票务系统,我正在尝试 运行 对其进行报告。我正在尝试获取每个用户接触的票数。
对于第一个查询:
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;
我能够列出特定用户接触的工单,并且可以手动计算它们:
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
但是当我尝试删除 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;
我的计数不正确:
UserID count
9 2
28 1
31 1
42 1
80 5
95 1
99 6
108 4
116 12
117 26
123 24
如您所见,UserID 80 的计数应该是 11。其他大多数结果也不正确,它们似乎都低于我的预期。
在子查询上使用 GROUP BY/COUNT 时我做错了吗?如何更改我的查询以获得我想要的结果?
您只想要聚合吗?
SELECT UserID, COUNT(*)
FROM dcscontact.ticketevents
WHERE EventDateTime BETWEEN '2016-06-22' AND '2016-06-23'
GROUP BY UserID;
如果对于给定的用户,同一张工单可以在数据中出现多次,那么 COUNT(DISTINCT)
更合适:
SELECT UserID, COUNT(DISTINCT TicketID)
FROM dcscontact.ticketevents
WHERE EventDateTime BETWEEN '2016-06-22' AND '2016-06-23'
GROUP BY UserID;
为了获得每个用户触摸的工单数量,让我们从一个正确的查询开始:
SELECT count(*) as N, UserID
FROM dcscontact.ticketevents
WHERE EventDateTime BETWEEN '2016-06-22' AND '2016-06-23'
GROUP BY UserID;
GROUP BY
子句应始终包含 SELECT
子句中提到的所有非聚合列。要求 "the ticket ID and the number of tickets (per user)"!
没有意义
另外,SQL 标准说 ORDER BY
不能应用于子查询。最好将 ORDER BY
视为查看输出的便利,而不是在查询中使用的信息。
您还想了解有关 TicketID
和 EventDateTime
的一些信息。你不能要"the id of the count of the tickets",但你可以得到第一张和最后一张票。时间相同:
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;
注意最早的时间不一定是TicketID最小的时间。要获取有关每个用户的第一张票的所有信息以及计数,请加入两个信息来源:
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
我有一个票务系统,我正在尝试 运行 对其进行报告。我正在尝试获取每个用户接触的票数。 对于第一个查询:
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;
我能够列出特定用户接触的工单,并且可以手动计算它们:
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
但是当我尝试删除 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;
我的计数不正确:
UserID count
9 2
28 1
31 1
42 1
80 5
95 1
99 6
108 4
116 12
117 26
123 24
如您所见,UserID 80 的计数应该是 11。其他大多数结果也不正确,它们似乎都低于我的预期。
在子查询上使用 GROUP BY/COUNT 时我做错了吗?如何更改我的查询以获得我想要的结果?
您只想要聚合吗?
SELECT UserID, COUNT(*)
FROM dcscontact.ticketevents
WHERE EventDateTime BETWEEN '2016-06-22' AND '2016-06-23'
GROUP BY UserID;
如果对于给定的用户,同一张工单可以在数据中出现多次,那么 COUNT(DISTINCT)
更合适:
SELECT UserID, COUNT(DISTINCT TicketID)
FROM dcscontact.ticketevents
WHERE EventDateTime BETWEEN '2016-06-22' AND '2016-06-23'
GROUP BY UserID;
为了获得每个用户触摸的工单数量,让我们从一个正确的查询开始:
SELECT count(*) as N, UserID
FROM dcscontact.ticketevents
WHERE EventDateTime BETWEEN '2016-06-22' AND '2016-06-23'
GROUP BY UserID;
GROUP BY
子句应始终包含 SELECT
子句中提到的所有非聚合列。要求 "the ticket ID and the number of tickets (per user)"!
另外,SQL 标准说 ORDER BY
不能应用于子查询。最好将 ORDER BY
视为查看输出的便利,而不是在查询中使用的信息。
您还想了解有关 TicketID
和 EventDateTime
的一些信息。你不能要"the id of the count of the tickets",但你可以得到第一张和最后一张票。时间相同:
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;
注意最早的时间不一定是TicketID最小的时间。要获取有关每个用户的第一张票的所有信息以及计数,请加入两个信息来源:
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