如何在按非唯一列排序后获取指定主键ID后的前N行SQL查询
解决方案
要实现目标,核心是匹配排序规则中的"之后"逻辑:既包含Size更大的行,也包含Size相同但ID更大的行。以下是两种可行的实现方式:
方法一:直接通过排序键筛选
利用原排序规则(Size ASC, ID ASC),构建精准的WHERE条件,筛选出ID=2的行之后的所有数据,再排序取前3:
SELECT * FROM foo WHERE (Size > (SELECT Size FROM foo WHERE ID = 2)) OR (Size = (SELECT Size FROM foo WHERE ID = 2) AND ID > 2) ORDER BY Size ASC, ID ASC LIMIT 3;
执行结果完全符合预期:
| ID | Size |
|---|---|
| 3 | 3 |
| 5 | 7 |
| 1 | 8 |
方法二:使用窗口函数(更通用)
通过窗口函数ROW_NUMBER()给排序后的每行分配序号,再筛选出ID=2的行的序号之后的前3行,适合排序规则更复杂的场景:
WITH ranked_foo AS ( SELECT *, ROW_NUMBER() OVER (ORDER BY Size ASC, ID ASC) AS row_num FROM foo ) SELECT ID, Size FROM ranked_foo WHERE row_num > (SELECT row_num FROM ranked_foo WHERE ID = 2) ORDER BY row_num LIMIT 3;
为什么之前的尝试失败?
- 第一种SQL只筛选了
Size > 3的行,漏掉了同Size但ID更大的ID=3的行; - 第二种SQL筛选
Size >= 3的行,但包含了排序在ID=2之前的ID=0的行,且LIMIT 3截断了后续正确数据。
内容的提问来源于stack exchange,提问作者jsiller
相关产品推荐
相关产品推荐

