You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

MySQL:如何查询指定整数存在于CSV格式文本列的记录

问题描述

现有一张数据表,其中linked_folders为文本类型字段,以CSV格式存储其他记录的引用,示例数据如下:

+----+----------------+
| id | linked_folders |
+----+----------------+
| 90 |    NULL        |
| 91 |    NULL        |
| 92 |    123,1,4,40  |
| 93 |    123,1       |
| 94 |    NULL        |
| 95 |    235,8       |
| 96 |    90          |
| 97 |    NULL        |
| 98 |    NULL        |
| 99 |    NULL        |
+----+----------------+

给定$id = 90,想要执行类似下面的伪查询:

SELECT * FROM my_table WHERE id = $id OR $id is in linked_folders

预期返回id为90和96的行。需求是匹配指定值存在于linked_folders字段的记录,但因为无法确定值前后是否有逗号,普通LIKE语句无法准确满足需求,求替代方案。

解决方案

方法1:拼接分隔符后精准匹配

给linked_folders字段前后都加上逗号,同时给目标id也包裹逗号,再用LIKE匹配,彻底避免部分值误判的问题:

SELECT * FROM my_table 
WHERE id = 90 
OR CONCAT(',', linked_folders, ',') LIKE '%,90,%';

比如linked_folders值为90时,拼接后变成,90,,能精准匹配%,90,%;如果是190,20这类包含90但不是独立值的情况,拼接后是,190,20,,不会被匹配到。

方法2:利用数据库内置的CSV处理函数

不同数据库提供了专门处理逗号分隔字符串的函数,直接用这些函数更简洁:

  • MySQL:用FIND_IN_SET函数,专门查找值在逗号分隔字符串中的位置,找到则返回大于0的结果:
SELECT * FROM my_table 
WHERE id = 90 
OR FIND_IN_SET(90, linked_folders) > 0;

注:FIND_IN_SET会自动忽略NULL值,无需额外处理。

  • PostgreSQL:将字符串转成数组后用ANY匹配:
SELECT * FROM my_table 
WHERE id = 90 
OR 90 = ANY(string_to_array(linked_folders, ','));
  • SQL Server:用STRING_SPLIT拆分后关联匹配:
SELECT DISTINCT t.* FROM my_table t
LEFT JOIN STRING_SPLIT(t.linked_folders, ',') s ON s.value = '90'
WHERE t.id = 90 OR s.value IS NOT NULL;

方法3:重构数据表(最优长期方案)

如果数据量较大或需要频繁执行这类查询,建议直接重构表结构,用关联表替代CSV存储:
新建一张folder_links表,包含parent_id(原表的id)和linked_id(关联的记录id)两个字段,把原表中linked_folders的每个值拆成单独的行。比如原表id=96的linked_folders是90,就在关联表插入一行(96,90);id=92的linked_folders是123,1,4,40,就插入四行(92,123)、(92,1)、(92,4)、(92,40)。

之后查询用关联方式,效率更高也更符合数据库设计规范:

SELECT t.* FROM my_table t
LEFT JOIN folder_links fl ON t.id = fl.parent_id
WHERE t.id = 90 OR fl.linked_id = 90;

内容的提问来源于stack exchange,提问作者ESB691

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.15 18:42:46