MySQL排序后如何定位指定ID的前后行?
解决MySQL中按自定义排序查找特定ID前后行的问题
针对你描述的场景,因为ID和自定义排序(Date升序 → Name升序)无关联,直接通过ID大小判断前后行不可行,这里提供两种实用方案:
方案1:基于子查询的兼容方案(适配所有MySQL版本)
步骤1:获取目标行的排序关键值
先拿到目标ID对应的Date和Name,作为后续查询的基准:
SELECT `Date`, `Name` FROM your_table WHERE ID = 7;
步骤2:查询前一行(排序中位于目标行之前的最后一条记录)
筛选所有排序优先级低于目标行的记录,再按排序规则倒序取第一条:
SELECT * FROM your_table WHERE (`Date` < (SELECT `Date` FROM your_table WHERE ID = 7)) OR (`Date` = (SELECT `Date` FROM your_table WHERE ID = 7) AND `Name` < (SELECT `Name` FROM your_table WHERE ID = 7)) ORDER BY `Date` DESC, `Name` DESC LIMIT 1;
步骤3:查询后一行(排序中位于目标行之后的第一条记录)
筛选所有排序优先级高于目标行的记录,按排序规则正序取第一条:
SELECT * FROM your_table WHERE (`Date` > (SELECT `Date` FROM your_table WHERE ID = 7)) OR (`Date` = (SELECT `Date` FROM your_table WHERE ID = 7) AND `Name` > (SELECT `Name` FROM your_table WHERE ID = 7)) ORDER BY `Date` ASC, `Name` ASC LIMIT 1;
方案2:窗口函数方案(MySQL 8.0及以上版本推荐)
利用ROW_NUMBER()窗口函数给每行按规则分配行号,再通过行号定位前后行,代码更简洁:
WITH ranked_rows AS ( SELECT *, ROW_NUMBER() OVER (ORDER BY `Date` ASC, `Name` ASC) AS row_num FROM your_table ) SELECT * FROM ranked_rows WHERE row_num = (SELECT row_num - 1 FROM ranked_rows WHERE ID = 7) OR row_num = (SELECT row_num + 1 FROM ranked_rows WHERE ID = 7);
边界情况说明
如果目标行是排序后的第一行,前一行查询会返回空;如果是最后一行,后一行查询会返回空,符合实际场景需求。
内容的提问来源于stack exchange,提问作者DaltonRandall
相关产品推荐
相关产品推荐

