MySQL使用LIKE运算符导致id > ?条件失效重复返回数据
问题原因
SQL中AND运算符的优先级高于OR,你拼接LIKE查询时没有给OR连接的匹配条件加括号,导致实际查询逻辑和预期完全不符,问题和LIKE语法本身无关。
你预期的筛选逻辑是:在满足id游标分页、隐藏状态、经纬度范围这些条件的基础上,再匹配「分类包含关键词」或「标题包含关键词」。但实际拼接出的WHERE子句会按运算符优先级解析为:
WHERE -- 第一组条件:只要分类匹配关键词,无视后续所有筛选规则直接命中 1=1 AND category LIKE ? OR -- 第二组条件:标题匹配关键词,同时满足分页、状态、经纬度要求 title LIKE ? AND id > ? AND 经纬度筛选 AND hidden = false
这种情况下,只要库中存在一条分类匹配关键词的记录,它会完全绕过id > ?的分页规则,每次查询都会被命中,又因为你写了LIMIT 1,每次请求都会优先返回这条固定记录,表现为始终拉取到相同行。
你之前用=做精确匹配时"运行正常"只是刚好测试数据没触发逻辑漏洞而已,只要存在分类精确匹配关键词、但不满足后续分页/状态/经纬度条件的记录,=写法一样会出现重复拉取的问题。
修复方案
- 给OR连接的两个匹配条件加括号,明确运算优先级,让两个匹配规则作为一个整体和其他筛选条件并列,修改分类筛选部分的代码:
if(typeof(req.body.category) == 'string' && req.body.category.trim() !== '') { query += ' AND (category LIKE ? OR title LIKE ?)'; arr.push('%' + req.body.category + '%', '%' + req.body.category + '%'); }
- 补充明确的排序规则:MySQL没有指定ORDER BY时不保证返回结果的固定顺序,游标分页必须按游标字段排序,否则会出现乱序、漏数问题。把查询结尾的语句修改为:
query += ' AND hidden = false ORDER BY id ASC LIMIT 1';
内容的提问来源于stack exchange,提问作者Johnathan M
相关产品推荐
相关产品推荐

