使用 MySQL 查询获取特定行的排名

Get position rank of specific row using MySQL query

我有 2 个 table:

每个用户都必须阅读一本书才能完成课程。系统会跟踪 table checked 中用户阅读的每一行。用户排名取决于他们阅读了多少行;你读的越多,你的排名就越好。

例如有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 解决方法查询的演示:

Demo