PostgreSQL:检查逗号分隔字符串与列中值匹配并返回ID
1 java,php
2 jquery,javascript
3 java
4 php,jquery
只要`searchval`中任意逗号分隔值与`keyword`列的逗号分隔值匹配,就返回对应的`id`,预期结果为:
1 (java,php is there), 3 (java is there), 4 (php is there)
请问该如何实现? --- # 解决方案 ### 方法一:MySQL专属快速实现 如果你用的是MySQL,那`FIND_IN_SET()`函数正好适配这个场景!它能直接检测单个值是否存在于逗号分隔的字符串中,返回值大于0就代表匹配成功。 直接执行下面的SQL语句就能得到目标结果: ```sql SELECT id, keyword FROM your_table_name WHERE FIND_IN_SET('php', keyword) > 0 OR FIND_IN_SET('java', keyword) > 0 OR FIND_IN_SET('html', keyword) > 0;
要是searchval是程序里的动态变量,你可以先把它按逗号拆成单个关键词,再动态拼接这些OR条件即可。
方法二:通用字符串匹配(适配多数数据库)
如果你的数据库不支持FIND_IN_SET,可以用字符串拼接加模糊匹配的方式——不过要注意避免部分匹配的坑(比如别让java误匹配到javascript)。我们给keyword前后都加上逗号,再检查目标关键词是否被逗号包裹:
SELECT id, keyword FROM your_table_name WHERE CONCAT(',', keyword, ',') LIKE '%,php,%' OR CONCAT(',', keyword, ',') LIKE '%,java,%' OR CONCAT(',', keyword, ',') LIKE '%,html,%';
这种写法在PostgreSQL、SQL Server等数据库都能正常运行,兼容性拉满。
重要优化建议
最后必须提醒一句:尽量不要在数据库里存储逗号分隔的字符串! 这种设计违反了数据库第三范式,不仅查询效率低(无法利用索引),后续增删单个关键词、统计关键词频率都会变得异常麻烦。
更合理的方案是拆分成关联表:
- 建
items表存储主数据(仅保留原表的id) - 建
keywords表,每条记录存一个独立关键词(比如id:1, name:php;id:2, name:java) - 建
item_keyword关联表,通过item_id和keyword_id关联商品与关键词
这样查询既高效又灵活:
SELECT DISTINCT i.id FROM items i JOIN item_keyword ik ON i.id = ik.item_id JOIN keywords k ON ik.keyword_id = k.id WHERE k.name IN ('php', 'java', 'html');
后续维护关键词也会方便很多,强烈建议改成这种结构!
内容的提问来源于stack exchange,提问作者Deepu Sasidharan
相关产品推荐
相关产品推荐

