我一直在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

推荐答案

您需要一些唯一的列来打破平局,因此可以删除VIEWER_COUNT=4的冗余行.

下面是一个示例,其中我向窗口函数添加了一个ORDER BY ... id ASC,然后使用row_number()而不是rank():

WITH w1 AS (
    SELECT *,
           ROW_NUMBER() OVER (
               PARTITION BY viewer_id, event_id
               ORDER BY viewer_count DESC, 
                        id ASC                   -- here
           ) AS ROWNUM
    FROM event_viewers
)
SELECT id, event_id, viewer_id, name, viewer_count
FROM w1
WHERE ROWNUM = 1
ORDER BY `event_id`, `viewer_id`;

Mysql相关问答推荐

为什么我的带有索引字段和非索引字段的 Select 有时需要很长时间

MySQL-如何检测时间戳中的一天

SQL 请求:REPLACE 和通配符 %.如何做正确的事?

使用Workbench时如何添加mysqldump配置标志

如何在 MySQL 中使用从 SELECT IF 返回的布尔值

如何让连续 3 周或以上的用户有订单?

基于 3 个条件 Select 3 行的最佳 MySQL 索引和查询

了解 SQL 中的元组语法

mysql错误:错误1018(HY000):无法读取'.'的目录(错误号:13)

将 MySQL 查询的输出转换为 utf8

Python MYSQL 更新语句

MySQL PHP - Select WHERE id = array()?

在 spring-boot jpa hibernate 中 >4<24 后与 Db 的连接终止

MySQL嵌套 Select 查询?

从mysql中的大表中快速 Select 随机行

在mysql中复制没有数据的数据库 struct (带有空表)

phpMyAdmin - 无法连接 - 无效设置 - 自从我添加了 root 密码 - 被锁定

在osx的命令行中使用Mysql-找不到命令?

"SELECT COUNT(*)" 很慢,即使有 where 子句

什么是mysql的BETWEEN性能超过..?