使用 MySQL 查询获取特定行的排名
Get position rank of specific row using MySQL query
我有 2 个 table:
- 用户
- 已检查
每个用户都必须阅读一本书才能完成课程。系统会跟踪 table checked
中用户阅读的每一行。用户排名取决于他们阅读了多少行;你读的越多,你的排名就越好。
例如有5个用户:
- Andres,读了8行(Andres的位置应该是1)
- Romina,读了7行(Romina的位置应该是2)
- John,阅读了 5 行(John 的位置应该是 3)
- Mona,读了5行(Mona的位置应该是3)
- Joey,已读0行(Joey的位置应该是5)
这是一个 sqlfiddle 的结构和数据。我在这个例子中使用 John:
获取 John 阅读的所有行:
SELECT COUNT(*) AS q FROM checked WHERE id_user = 3;
获取所有用户的列表,按排名顺序排列:
SELECT
user.id_user AS id_user,
user.name AS name,
COUNT(checked.id_check) AS q
FROM user
JOIN checked ON checked.id_user = user.id_user
GROUP BY checked.id_user ORDER BY q;
问题是我仍然需要一种方法来获取特定用户的排名,仅此而已。对于 John 示例,查询应该 return 3.
如果我们仍然以John为例,我的初步想法是获取John的阅读行数,然后统计所有阅读行数大于John的用户,并加1。
如何将其放入 MySQL (5.6) 查询中?当然也欢迎其他选择!
有什么想法吗?谢谢!
您正在寻找 RANK()
解析函数:
SELECT
u.id_user AS id_user,
u.name AS name,
COUNT(c.id_check) AS q,
RANK() OVER (ORDER BY COUNT(c.id_check) DESC) position
FROM user u
LEFT JOIN checked c
ON c.id_user = u.id_user
GROUP BY
u.id_user,
u.name
ORDER BY
q;
请注意 RANK
需要 MySQL 版本 8 或更高版本。如果你使用的是MySQL的早期版本,模拟rank的方法是有的,但是比较难看,如果你希望有长期的需求,那就考虑升级吧。
编辑:
MySQL 5.7 版及更早版本的一种可能解决方法是使用相关子查询来查找排名:
SELECT
id_user,
name,
q,
1 + (SELECT COUNT(*) FROM
(SELECT COUNT(c.id_check) cnt FROM user u
LEFT JOIN checked c ON c.id_user = u.id_user
GROUP BY c.id_user) t
WHERE q < t.cnt) AS `rank`
FROM
(
SELECT
u.id_user AS id_user,
u.name AS name,
COUNT(c.id_check) AS q
FROM user u
LEFT JOIN checked c
ON c.id_user = u.id_user
GROUP BY
u.id_user,
u.name
) t;
这是 MySQL 5.7 解决方法查询的演示:
我有 2 个 table:
- 用户
- 已检查
每个用户都必须阅读一本书才能完成课程。系统会跟踪 table checked
中用户阅读的每一行。用户排名取决于他们阅读了多少行;你读的越多,你的排名就越好。
例如有5个用户:
- Andres,读了8行(Andres的位置应该是1)
- Romina,读了7行(Romina的位置应该是2)
- John,阅读了 5 行(John 的位置应该是 3)
- Mona,读了5行(Mona的位置应该是3)
- Joey,已读0行(Joey的位置应该是5)
这是一个 sqlfiddle 的结构和数据。我在这个例子中使用 John:
获取 John 阅读的所有行:
SELECT COUNT(*) AS q FROM checked WHERE id_user = 3;
获取所有用户的列表,按排名顺序排列:
SELECT
user.id_user AS id_user,
user.name AS name,
COUNT(checked.id_check) AS q
FROM user
JOIN checked ON checked.id_user = user.id_user
GROUP BY checked.id_user ORDER BY q;
问题是我仍然需要一种方法来获取特定用户的排名,仅此而已。对于 John 示例,查询应该 return 3.
如果我们仍然以John为例,我的初步想法是获取John的阅读行数,然后统计所有阅读行数大于John的用户,并加1。
如何将其放入 MySQL (5.6) 查询中?当然也欢迎其他选择!
有什么想法吗?谢谢!
您正在寻找 RANK()
解析函数:
SELECT
u.id_user AS id_user,
u.name AS name,
COUNT(c.id_check) AS q,
RANK() OVER (ORDER BY COUNT(c.id_check) DESC) position
FROM user u
LEFT JOIN checked c
ON c.id_user = u.id_user
GROUP BY
u.id_user,
u.name
ORDER BY
q;
请注意 RANK
需要 MySQL 版本 8 或更高版本。如果你使用的是MySQL的早期版本,模拟rank的方法是有的,但是比较难看,如果你希望有长期的需求,那就考虑升级吧。
编辑:
MySQL 5.7 版及更早版本的一种可能解决方法是使用相关子查询来查找排名:
SELECT
id_user,
name,
q,
1 + (SELECT COUNT(*) FROM
(SELECT COUNT(c.id_check) cnt FROM user u
LEFT JOIN checked c ON c.id_user = u.id_user
GROUP BY c.id_user) t
WHERE q < t.cnt) AS `rank`
FROM
(
SELECT
u.id_user AS id_user,
u.name AS name,
COUNT(c.id_check) AS q
FROM user u
LEFT JOIN checked c
ON c.id_user = u.id_user
GROUP BY
u.id_user,
u.name
) t;
这是 MySQL 5.7 解决方法查询的演示: