我在MySQL的排行榜实施中遇到了特定情况的问题。
我有一个用户和帖子表,每个帖子都有获奖点数。帖子可以分为多个类别( activityUid 和 activityType )。排行榜根据每个类别的每个用户发布的最佳帖子进行排名。
由于获奖积分不是唯一的(Y类中用户X的多个帖子可能会获得相同数量的积分),我遇到的情况是我的查询不再返回每个用户的最佳帖子,但多个帖子具有相同的最大点数。
如果点数重复,我希望将结果范围缩小到每位用户的最近帖子( dateCreated )。
查询:
SELECT main.*, @curRank := @curRank + 1 AS rank
FROM (
SELECT users.userUid, posts.postUid, posts.points, posts.dateCreated
FROM users
INNER JOIN posts ON users.userUid = posts.userUid
INNER JOIN (
SELECT userUid, max(points) AS maxPoints
FROM posts
WHERE isLift = 1 AND verified = 1 AND activityUid = 'OP0iEbpmP36fkJdMTL2S' AND activityType = 'MAX_WEIGHT'
GROUP BY userUid
ORDER BY maxPoints DESC
) AS maxPerUser ON users.userUid = maxPerUser.userUid AND posts.points = maxPerUser.maxPoints
WHERE isLift = 1 AND verified= 1 AND activityUid = 'OP0iEbpmP36fkJdMTL2S' AND activityType = 'MAX_WEIGHT'
ORDER BY maxPerUser.maxPoints DESC, posts.dateCreated DESC
) AS main
JOIN (SELECT @curRank:= 0) r
ORDER BY rank ASC;
输出:
+------------------------------+--------------------------------------+--------+---------------------+------+
| userUid | postUid | points | dateCreated | rank |
+------------------------------+--------------------------------------+--------+---------------------+------+
| RRyUFdaXsEO6DJOJDL8u7gu1aZ13 | cf6f54d0-336a-11e8-847c-2f396385505a | 303 | 2018-03-29 16:04:21 | 1 |
| jkLbDkRkaoUG4A851VjiEdWnNN32 | 8ada4110-3336-11e8-baaa-1755b4dadd4d | 302 | 2018-03-29 09:50:12 | 2 |
| jkLbDkRkaoUG4A851VjiEdWnNN32 | 4bee45d0-31ad-11e8-8072-2b86c9f79738 | 302 | 2018-03-27 10:55:06 | 3 |
| jkLbDkRkaoUG4A851VjiEdWnNN32 | 2fec75e0-31a9-11e8-8072-2b86c9f79738 | 302 | 2018-03-27 10:25:40 | 4 |
+------------------------------+--------------------------------------+--------+---------------------+------+
期望的结果:
+------------------------------+--------------------------------------+--------+---------------------+------+
| userUid | postUid | points | dateCreated | rank |
+------------------------------+--------------------------------------+--------+---------------------+------+
| RRyUFdaXsEO6DJOJDL8u7gu1aZ13 | cf6f54d0-336a-11e8-847c-2f396385505a | 303 | 2018-03-29 16:04:21 | 1 |
| jkLbDkRkaoUG4A851VjiEdWnNN32 | 8ada4110-3336-11e8-baaa-1755b4dadd4d | 302 | 2018-03-29 09:50:12 | 2 |
+------------------------------+--------------------------------------+--------+---------------------+------+
有谁知道是否有可能实现所描述的功能?谢谢!
表架构(简化):
CREATE TABLE `users` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`userUid` varchar(255) COLLATE utf8mb4_bin NOT NULL DEFAULT '',
PRIMARY KEY (`id`),
UNIQUE KEY `userUid` (`userUid`)
) ENGINE=InnoDB AUTO_INCREMENT=71 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin;
CREATE TABLE `posts` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`postUid` varchar(255) COLLATE utf8mb4_bin NOT NULL DEFAULT '',
`isLift` tinyint(1) NOT NULL,
`userUid` varchar(48) COLLATE utf8mb4_bin NOT NULL DEFAULT '',
`activityUid` varchar(255) COLLATE utf8mb4_bin DEFAULT NULL,
`activityType` varchar(255) COLLATE utf8mb4_bin DEFAULT NULL,
`points` smallint(6) unsigned DEFAULT NULL,
`verified` tinyint(1) DEFAULT NULL,
`dateCreated` datetime DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (`id`),
UNIQUE KEY `postUid` (`postUid`),
KEY `userUid` (`userUid`),
KEY `isLift` (`isLift`),
KEY `activityUid` (`activityUid`),
KEY `activityType` (`activityType`),
KEY `points` (`points`),
KEY `dateCreated` (`dateCreated`),
KEY `verified` (`verified`),
CONSTRAINT `posts_ibfk_1` FOREIGN KEY (`userUid`) REFERENCES `users` (`userUid`)
) ENGINE=InnoDB AUTO_INCREMENT=862 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin;
示例数据集:
INSERT INTO `users` (`id`, `userUid`)
VALUES
(1, 'jkLbDkRkaoUG4A851VjiEdWnNN32'),
(2, 'RRyUFdaXsEO6DJOJDL8u7gu1aZ13');
INSERT INTO `posts` (`id`, `postUid`, `isLift`, `userUid`, `activityUid`, `activityType`, `points`, `verified`, `dateCreated`)
VALUES
(1, '4adcc1b0-1e18-11e8-abc6-2f6e24661429', 1, 'jkLbDkRkaoUG4A851VjiEdWnNN32', 'OP0iEbpmP36fkJdMTL2S', 'MAX_WEIGHT', 30, 1, '2018-03-02 12:51:44'),
(2, '2fec75e0-31a9-11e8-8072-2b86c9f79738', 1, 'jkLbDkRkaoUG4A851VjiEdWnNN32', 'OP0iEbpmP36fkJdMTL2S', 'MAX_WEIGHT', 302, 1, '2018-03-27 10:25:40'),
(3, '4bee45d0-31ad-11e8-8072-2b86c9f79738', 1, 'jkLbDkRkaoUG4A851VjiEdWnNN32', 'OP0iEbpmP36fkJdMTL2S', 'MAX_WEIGHT', 302, 1, '2018-03-27 10:55:06'),
(4, '61bf2ee0-3272-11e8-bc76-611e04d7551e', 1, 'jkLbDkRkaoUG4A851VjiEdWnNN32', 'OP0iEbpmP36fkJdMTL2S', 'MAX_WEIGHT', 56, 1, '2018-03-28 10:25:57'),
(5, '8ada4110-3336-11e8-baaa-1755b4dadd4d', 1, 'jkLbDkRkaoUG4A851VjiEdWnNN32', 'OP0iEbpmP36fkJdMTL2S', 'MAX_WEIGHT', 302, 1, '2018-03-29 09:50:12'),
(6, 'cf6f54d0-336a-11e8-847c-2f396385505a', 1, 'RRyUFdaXsEO6DJOJDL8u7gu1aZ13', 'OP0iEbpmP36fkJdMTL2S', 'MAX_WEIGHT', 303, 1, '2018-03-29 16:04:21');
答案 0 :(得分:1)
将表posts
替换为查询以提取每个UserUid
/ Points
的最新帖子(dateCreated)。
SELECT main.*, @curRank := @curRank + 1 AS rank
FROM (
SELECT users.userUid, posts.postUid, posts.points, posts.dateCreated
FROM users
INNER JOIN (select * from
posts p where datecreated = (select max(datecreated)
from posts where posts.userUid = p.userUid
and posts.points = p.points)
) posts ON users.userUid = posts.userUid
INNER JOIN (
SELECT userUid, max(points) AS maxPoints
FROM posts
WHERE isLift = 1 AND verified = 1 AND activityUid = 'OP0iEbpmP36fkJdMTL2S' AND activityType = 'MAX_WEIGHT'
GROUP BY userUid
ORDER BY maxPoints DESC
) AS maxPerUser ON users.userUid = maxPerUser.userUid AND posts.points = maxPerUser.maxPoints
WHERE isLift = 1 AND verified= 1 AND activityUid = 'OP0iEbpmP36fkJdMTL2S' AND activityType = 'MAX_WEIGHT'
ORDER BY maxPerUser.maxPoints DESC, posts.dateCreated DESC
) AS main
JOIN (SELECT @curRank:= 0) r
ORDER BY rank ASC;