如何用SQL获取指定id在排序后结果集中的队列位置?
嘿,我来帮你解决这个问题!要获取id=5的行在priority ASC, created DESC这个排序规则下的行号,有两种实用的方法,我给你详细拆解下:
方法一:用窗口函数ROW_NUMBER()(推荐,简洁直观)
如果你的数据库支持窗口函数(比如MySQL 8.0+、PostgreSQL、SQL Server这些现代版本),这是最省心的方式。我们先给排序后的每一行分配行号,再筛选目标行即可:
SELECT rn AS position FROM ( SELECT id, ROW_NUMBER() OVER (ORDER BY priority ASC, created DESC) AS rn FROM tickets ) AS ranked_tickets WHERE id = 5;
简单解释下:内层查询通过ROW_NUMBER()函数,按照你要求的排序规则给每一行生成唯一的行号rn;外层查询直接筛选id=5的行,就能得到它在排序队列中的位置。
方法二:用COUNT(*)统计前置行数(兼容旧版本数据库)
要是你用的是不支持窗口函数的老版本数据库(比如MySQL 5.x),可以基于你最初的思路优化,统计所有排在id=5前面的行数,再加1就是它的位置:
SELECT COUNT(*) + 1 AS position FROM tickets WHERE priority < (SELECT priority FROM tickets WHERE id = 5) OR (priority = (SELECT priority FROM tickets WHERE id = 5) AND created > (SELECT created FROM tickets WHERE id = 5));
这个逻辑的核心是:
- 先拿到id=5的行的
priority和created值 - 统计所有满足以下任一条件的行:要么
priority比它小(会排在前面),要么priority相同但created时间更晚(因为排序是created降序,晚的时间排前面) - 最后加1,因为count的是前面的行数,目标行的位置就是前置行数+1
验证结果
根据你提供的tickets数据,按照priority ASC, created DESC排序后的行顺序是:
- id=3(priority=1,created=2018-05-27 16:01:15)
- id=2(priority=2,created=2018-05-27 16:00:54)
- id=6(priority=3,created=2018-05-27 16:01:39)
- id=1(priority=3,created=2018-05-27 16:00:54)
- id=5(priority=4,created=2018-05-27 16:01:39)
- id=4(priority=5,created=2018-05-27 16:01:15)
可以看到id=5的行号是5,用上面两种方法都会得到正确的结果。
内容的提问来源于stack exchange,提问作者R1KO
相关产品推荐
相关产品推荐

