MySQL如何选取非连续ID表中第2至第5行的记录?
这个报错的原因很明确——MySQL的执行顺序不允许在WHERE子句里直接引用SELECT中定义的别名。
具体来说,SQL语句的执行流程是:先处理FROM/JOIN部分,然后执行WHERE过滤,最后才会执行SELECT里的列计算和别名赋值。所以当你写WHERE row_number BETWEEN 2 AND 5时,MySQL还不知道row_number这个列存在,自然会报错。
接下来给你两种可行的解决方案:
方案1:兼容旧版本MySQL的子查询写法
把生成行号的逻辑放到子查询里,在外层查询中再过滤行号范围:
SELECT row_number, id, name FROM ( SELECT @curRow := @curRow + 1 AS row_number, p.id, p.name FROM product_image p JOIN (SELECT @curRow := 0) r ORDER BY p.id -- 必须加排序,保证行号顺序稳定 ) AS numbered_rows WHERE row_number BETWEEN 2 AND 5;
这里要注意两个关键点:
- 子查询里必须同时选出你需要的
id和name列,不然外层拿不到原始数据 - 一定要加上
ORDER BY p.id,否则MySQL返回的行顺序是不确定的,行号分配会随机,导致你拿到的不是预期的记录
方案2:MySQL 8.0+推荐的窗口函数写法
如果你的MySQL版本是8.0或更高,用ROW_NUMBER()窗口函数会更简洁规范,不需要手动维护变量:
SELECT row_number, id, name FROM ( SELECT ROW_NUMBER() OVER (ORDER BY id) AS row_number, id, name FROM product_image ) AS numbered_rows WHERE row_number BETWEEN 2 AND 5;
窗口函数ROW_NUMBER()会自动按你指定的排序规则(这里是ORDER BY id)生成连续的行号,逻辑更清晰,也不容易出错。
执行上面任意一种写法,你就能拿到表中按id排序后的第2到第5行记录(也就是name为B、C、D、E的四条数据)。
内容的提问来源于stack exchange,提问作者Toma Tomov
相关产品推荐
相关产品推荐

