MySQL LIKE 与 json_extract

Posted

技术标签:

【中文标题】MySQL LIKE 与 json_extract【英文标题】:MySQL LIKE with json_extract 【发布时间】:2020-07-22 11:18:48 【问题描述】:

我有一个 mysql 查询,我在其中按 json 字段过滤:

SELECT id, username 
FROM   (SELECT id, 
               Json_extract(payload, '$.username') AS username 
        FROM   table1) AS tmp 
WHERE  username = 'userName1'; 

返回 1 行,如下所示:

1, "userName1"看到子句中没有的引号了吗?

我需要使WHERE 子句不区分大小写。 但是当我这样做时

WHERE username LIKE 'userName1';

它返回 0 行。我不明白为什么它会这样工作,= 子句虽然没有双引号,但仍然有效。

如果我这样做了

WHERE username LIKE '%userName1%'; 现在也返回该行,因为%% 考虑了引号:

1, "userName1"

但是当我这样做时

WHERE username LIKE '%username1%'; 它返回 0 行,因此与通常的 MySQL LIKE 不同,它在某种程度上区分大小写。

我做错了什么以及如何以不区分大小写的方式过滤 json 有效负载? 编辑========================================== 猜测是这里应该使用COLLATE,但到目前为止我还不明白如何使它工作。

【问题讨论】:

我认为mysql默认不区分大小写。二进制操作时只区分大小写 LIKE 子句在 json 之外不区分大小写,可以使用任何字符串。但如果是 json,它的工作原理是这样的 当您需要 MySQL 在字符串内部翻找时,请重新考虑使用 JSON。相反,可能值得将该字段拆分为单独的列。 【参考方案1】:

MySQL 的默认排序规则是 latin1_swedish_ci before 8.0 和 utf8mb4_0900_ai_ci since 8.0。所以非二进制字符串比较在普通列中默认是不区分大小写的。

但是,正如MySQL manual for JSON type中提到的那样

MySQL 使用 utf8mb4 字符集和 utf8mb4_bin 排序规则处理 JSON 上下文中使用的字符串。"。

因此,您的 JSON 值在 utf8mb4_bin 排序规则中,您需要对任一操作数应用不区分大小写的排序规则,以使比较不区分大小写。

例如

WHERE username COLLATE XXX LIKE '...'

XXX 应该是 utf8mb4 排序规则(例如您提到的 utf8mb4_general_ci)。

或者

WHERE username LIKE '...' COLLATE YYY

其中YYY 应该是与您连接的字符集匹配的排序规则。

对于相等比较,您应该 unquote the JSON value 与 JSON_UNQUOTE() 或取消引用的提取运算符 ->>

例如

JSON_UNQUOTE(JSON_EXTRACT(payload, '$.username'))

或者干脆

payload->>'$.username'

JSON 类型和函数的工作方式与普通数据类型不同。看来你是新手。因此,我建议您在将其投入生产环境之前仔细阅读手册。

【讨论】:

【参考方案2】:

好的,我可以通过在LIKE 子句后添加COLLATE utf8mb4_general_ci 来解决不区分大小写的问题。

所以这里的重点是找到一个有效的排序规则,而它又可以通过研究您使用的数据库来找到。

【讨论】:

以上是关于MySQL LIKE 与 json_extract的主要内容,如果未能解决你的问题,请参考以下文章

mysql中json_extract函数的使用?作用是什么?

将使用 JSON_EXTRACT 的查询从 MySQL 转换为 BigQuery

MySQL JSON_EXTRACT 路径表达式错误

where子句中的mysql udf json_extract - 如何提高性能

where子句中的mysql udf json_extract - 如何提高性能

mysql5.7.23使用JSON_EXTRACT函数后返回结果集为空