CROSS JOIN JSON_TABLE搭配REGEXP_REPLACE与LOCATE结果异常排查
问题描述
我有一张含tags列的products表,该列存储逗号分隔的标签列表,例如отказвам резервацията, отмяна на резервацията。使用以下SQL查询:
SELECT * FROM products CROSS JOIN JSON_TABLE(CONCAT('["', REGEXP_REPLACE(tags, ', *', '","'), '"]'), '$[*]' COLUMNS(tag VARCHAR(20) PATH '$') ) AS j WHERE LOCATE(j.tag, 'отказвам резервацията');
插入两条测试记录:
INSERT INTO products VALUES ('отказвам резервацията'),('резервация');
尝试匹配отказвам резервацията时,却错误匹配到含резервация的记录,请问问题出在哪里?
问题原因
问题核心是**LOCATE函数的参数顺序搞反了**。LOCATE(substr, str)的逻辑是:查找substr在str中的位置,找到则返回大于0的数值,否则返回0。
你当前的写法LOCATE(j.tag, 'отказвам резервацията'),实际是在判断j.tag是否是отказвам резервацията的子串。当j.tag的值为резервация时,它恰好是отказвам резервацията的一部分,因此LOCATE返回有效位置,导致这条无关记录被错误匹配。
解决方案
根据需求选择以下两种写法:
1. 精确匹配标签
如果需要严格匹配完整标签,直接用相等判断即可:
SELECT * FROM products CROSS JOIN JSON_TABLE(CONCAT('["', REGEXP_REPLACE(tags, ', *', '","'), '"]'), '$[*]' COLUMNS(tag VARCHAR(20) PATH '$') ) AS j WHERE j.tag = 'отказвам резервацията';
2. 模糊匹配(标签包含目标字符串)
如果需要标签中包含目标字符串的匹配,修正LOCATE的参数顺序:
SELECT * FROM products CROSS JOIN JSON_TABLE(CONCAT('["', REGEXP_REPLACE(tags, ', *', '","'), '"]'), '$[*]' COLUMNS(tag VARCHAR(20) PATH '$') ) AS j WHERE LOCATE('отказвам резервацията', j.tag) > 0;
也可以用LIKE实现相同逻辑:
WHERE j.tag LIKE '%отказвам резервацията%';
内容的提问来源于stack exchange,提问作者lStoilov
相关产品推荐
相关产品推荐

