我一直在try 报告一个事件门户网站的观众统计数据.我注意到在很多情况下,人们会多次重新连接,所以我设计了一个viewer_id来将它们关联在一起.每次他们开始观看活动时,他们都会输入一个名字和观看人数(包括他们自己).
我希望能够 Select 按Event_id和view_id组合分组的事件视图,同时为该给定组合 Select 具有最大view_count的行.
Example Schema & Data
-- Server Version: MySQL 8.0.43
CREATE TABLE `event_viewers` (
`id` bigint unsigned NOT NULL AUTO_INCREMENT,
`event_id` bigint unsigned NOT NULL,
`viewer_id` bigint unsigned NOT NULL,
`name` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL,
`viewer_count` int NOT NULL,
PRIMARY KEY (`id`)
);
-- Event ID 1
insert into event_viewers (id, event_id, viewer_id, name, viewer_count)
values (1, 1, 1, 'Bert Kuvalis0', 1),
(6, 1, 2, 'Wanda Steuber0', 7),
(11, 1, 3, 'Erick Nienow0', 4),
(16, 1, 3, 'Erick Nienow1', 3),
(17, 1, 3, 'Erick Nienow2', 4);
-- Event ID 2
insert into event_viewers (id, event_id, viewer_id, name, viewer_count)
values (2, 2, 1, 'Bert Kuvalis2', 11),
(7, 2, 2, 'Wanda Steuber2', 10),
(12, 2, 3, 'Erick Nienow3', 7),
(18, 2, 2, 'Wanda Steuber3', 13);
我希望能够得到以下结果:
id | event_id | viewer_id | name | viewer_count |
---|---|---|---|---|
1 | 1 | 1 | Bert Kuvalis | 1 |
6 | 1 | 2 | Wanda Steuber0 | 7 |
11 | 1 | 3 | Erick Nienow0 | 4 |
2 | 2 | 1 | Bert Kuvalis2 | 11 |
18 | 2 | 2 | Wanda Steuber3 | 13 |
12 | 2 | 3 | Erick Nienow3 | 7 |
在上面的结果中,有一个记录具有相同的Event_id、view_id和amp;view_count,它具有最大的view_count,我已经解决了这个问题,方法是选取匹配的第一行(Id 11),丢弃第二行(Id 17).对于我的问题,我实际上并不关心哪个被选中(11或17),只要只有一个被选中.
我试过的东西:
分组依据
我最成功的try 是使用分组依据和MAX,但缺少基本行ID和名称.
SELECT
ev.event_id,
ev.viewer_id,
MAX(ev.`viewer_count`) AS `viewer_count`
FROM event_viewers as ev
分组依据 ev.viewer_id, ev.event_id ORDER BY `event_id`, `viewer_id`;
这将返回所需的输出,但不包括id和name列.
event_id | viewer_id | viewer_count |
---|---|---|
1 | 1 | 1 |
1 | 2 | 7 |
1 | 3 | 4 |
2 | 1 | 11 |
2 | 2 | 13 |
2 | 3 | 7 |
不存在的地方
我try 使用不存在的地方,看看是否可以排除重复项,更喜欢最大的.
SELECT DISTINCT ev1.* from event_viewers ev1
不存在的地方 (
SELECT * FROM event_viewers as ev2
WHERE ev2.viewer_id = ev1.viewer_id
AND ev2.event_id = ev1.event_id
AND ev2.viewer_count > ev1.viewer_count
) ORDER BY `event_id`, `viewer_id`;
结果见下文,因为不存在的地方、左连接和带窗Stry 都有相同的输出.它们包括一个额外的行,它有一个匹配的event_id,viewer_id和viewer_count,它显示了两次.(11和17都显示,只想要其中之一).
左连接
根据MySQL documentation on rows holding group-wise maximum of a certain column的建议,我try 使用左连接:
SELECT ev1.* FROM event_viewers ev1
左连接 event_viewers ev2
ON ( ev1.viewer_count<ev2.viewer_count AND ev1.viewer_id=ev2.viewer_id AND ev1.event_id=ev2.event_id )
WHERE ev2.id IS null
ORDER BY ev1.event_id, ev1.`viewer_id`;
结果见下文,因为不存在的地方、左连接和带窗Stry 都有相同的输出.它们包括一个额外的行,它有一个匹配的event_id,viewer_id和viewer_count,它显示了两次.(11和17都显示,只想要其中之一).
带窗
按照MySQL documentation on rows holding group-wise maximum of a certain column人的建议,我try 使用WITH:
WITH w1 AS (
SELECT *,
RANK() OVER (PARTITION BY viewer_id, event_id
ORDER BY viewer_count DESC
) AS `Rank`
FROM event_viewers
)
SELECT id, event_id, viewer_id, name, viewer_count
FROM w1
WHERE `Rank` = 1
ORDER BY `event_id`, `viewer_id`;
结果见下文,因为不存在的地方、左连接和带窗Stry 都有相同的输出.它们包括一个额外的行,它有一个匹配的event_id,viewer_id和viewer_count,它显示了两次.(11和17都显示,只想要其中之一).
id | event_id | viewer_id | name | viewer_count |
---|---|---|---|---|
1 | 1 | 1 | Bert Kuvalis | 1 |
6 | 1 | 2 | Wanda Steuber0 | 7 |
11 | 1 | 3 | Erick Nienow0 | 4 |
17 | 1 | 3 | Erick Nienow2 | 4 |
2 | 2 | 1 | Bert Kuvalis2 | 11 |
18 | 2 | 2 | Wanda Steuber3 | 13 |
12 | 2 | 3 | Erick Nienow3 | 7 |