MySQL如何实现数组包含列中任意值时筛选对应行?
MySQL筛选包含指定数组任意元素的字符串列数据
刚好碰到过类似的场景,给你分享几个可行的解决方案:
方法1:用FIND_IN_SET处理精准匹配
首先你的列值是(10,11,12)这种带括号的格式,得先把括号去掉转成标准的逗号分隔字符串,再用FIND_IN_SET来判断数组元素是否存在。
比如传入数组是[3,4,11],对应的SQL是:
SELECT * FROM your_table WHERE FIND_IN_SET('3', REPLACE(REPLACE(your_column, '(', ''), ')', '')) > 0 OR FIND_IN_SET('4', REPLACE(REPLACE(your_column, '(', ''), ')', '')) > 0 OR FIND_IN_SET('11', REPLACE(REPLACE(your_column, '(', ''), ')', '')) > 0;
- 优点:匹配精准,不会出现把
111误判为11的情况;逻辑清晰易懂。 - 缺点:如果数组元素很多,手动写一堆
OR会很麻烦,这时候可以在你的应用代码里动态生成这部分条件。
方法2:用正则表达式简化写法
如果数组元素比较多,用正则会更简洁。把数组元素用|拼接成匹配模式,再结合MySQL的单词边界[[:<:]]和[[:>:]]来避免部分匹配:
比如同样的数组[3,4,11],SQL可以写成:
SELECT * FROM your_table WHERE your_column REGEXP '[[:<:]](3|4|11)[[:>:]]';
- 优点:写法简洁,不管数组有多少元素,只需要拼接成
(元素1|元素2|...)的格式就行。 - 缺点:数据量很大的时候,正则的性能可能不如
FIND_IN_SET;另外一定要记得加单词边界,不然会出现比如11匹配到111的错误。
额外建议(长远优化方案)
如果这个查询是你业务里的高频操作,真心建议你改改表结构!这种把多个值存在一个字符串列里的设计,不仅查询麻烦,还很难做索引优化,扩展性也差。最好改成关联表的形式:比如新建一个子表,主表的每一行对应子表的多行数据(每个元素存一行),用外键关联主表ID。这样查询的时候用IN或者JOIN就能轻松搞定,性能和可维护性都会好很多。
内容的提问来源于stack exchange,提问作者Smart Cms
相关产品推荐
相关产品推荐

