MySQL使用多WHERE LIKE查询逗号分隔列包含指定数字的问题
错误根因
现有代码拼接生成的WHERE子句存在逻辑断层:
- 对数字数组映射生成匹配条件时,仅输出了LIKE的匹配值片段,没有为每个独立分支携带完整的判断逻辑前缀
concat(",", columnNumbers, ",") like - 最终实际执行的SQL等价于:
SELECT * FROM table WHERE concat(",", columnNumbers, ",") like '%,1,%' or '%,41,%' - 上述语句的执行逻辑可拆分为两部分判断:
- 校验拼接后的列值是否匹配
%,1,% - 常量字符串
'%,41,%'参与布尔判断:由于字符串首字符为非数字的%,MySQL会将其隐式转换为数值0(即逻辑假)
- 校验拼接后的列值是否匹配
- 整个查询实际仅保留了“列值中是否包含独立数字1”的单条判断,因此只会返回id=2的匹配结果,完全跳过了对数字41的校验逻辑
修正方法
调整数组映射的生成规则,为每个待校验数字生成完整的独立判断分支,再用OR运算符连接所有分支:
const numbers = [1, 41] // 为每个数字生成完整的匹配判断条件 const conditionList = numbers.map(n => `concat(",", columnNumbers, ",") LIKE '%,${n},%'` ).join(' OR ') const sql = `SELECT * FROM table WHERE ${conditionList}`
修正后生成的可执行SQL为:
SELECT * FROM table WHERE concat(",", columnNumbers, ",") LIKE '%,1,%' OR concat(",", columnNumbers, ",") LIKE '%,41,%'
该逻辑可正确匹配列值中包含1或41的独立数值,最终返回id=1、id=2两条符合预期的结果。
补充说明
- 在列值前后拼接逗号后再做LIKE匹配的设计,可有效避免子串误匹配:例如搜索数字1时,不会将21、11、14等包含字符1但非独立值的内容误判为命中,这部分逻辑设计是正确的
- 直接将未校验的输入拼接进SQL语句的写法存在SQL注入风险,生产环境需改用参数化查询传递LIKE的匹配值,禁止直接拼接外部可控的输入内容
内容的提问来源于stack exchange,提问作者Slinidy
相关产品推荐
相关产品推荐

