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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.22 13:17:20