MySQL - 搜索 JSON 数据列

Posted

技术标签:

【中文标题】MySQL - 搜索 JSON 数据列【英文标题】:MySQL - Search JSON data column 【发布时间】:2019-08-02 09:25:03 【问题描述】:

我有一个 mysql 数据库列,其中包含 JSON 数组编码的字符串。我想搜索“Elapsed”值大于特定数字的 JSON 数组,并返回找到该值的对象的相应 TaskID 值。我一直在尝试使用 JSON_SEARCH、JSON_CONTAINS 和 JSON_EXTRACT 函数的组合,但没有得到想要的结果。

[
    
        "TaskID": "TAS00000012344", 
        "Elapsed": "25"
    ,
    
        "TaskID": "TAS00000012345",
        "Elapsed": "30"
    ,
    
        "TaskID": "TAS00000012346",
        "Elapsed": "35"
    ,
    
        "TaskID": "TAS00000012347",
        "Elapsed": "40"
    
]

参考上面的 JSON,如果我搜索“Elapsed”>“30”,那么将返回 2 条记录

    'TAS00000012346' 'TAS00000012347'

我正在使用 MySQL 5.7.11 版,并且是查询 json 数据的新手。任何帮助,将不胜感激。谢谢

【问题讨论】:

你能展示一下你的表结构吗?如果我没记错的话,您必须将列定义为实际 JSON 类型,或者为了使用这些函数,您至少需要将 varchar 字段转换为 json 类型,请看这里:dev.mysql.com/doc/refman/5.7/en/json.html#json-paths “我有一个 MySQL 数据库列,其中包含 JSON 数组编码的字符串” 为什么? 包含 JSON 数据的列只是一个“文本”数据类型。无论数据类型如何,JSON 函数都可以正常工作。可能没有他们应该/可能的那么好。 【参考方案1】:

在 MySQL 8.0 之前,没有简单的方法将 JSON 数组转换为记录集(即,函数 JSON_TABLE() 尚不可用)。

因此,无论哪种方式,我们都需要手动遍历数组以提取相关数据(使用JSON_EXTRACT())。这是一个使用内联查询生成数字列表的解决方案;另一个经典的方法是使用数字表。

假设一个名为 mytable 的表具有一个名为 js 的列,其中包含 JSON 内容:

SELECT 
    JSON_EXTRACT(js, CONCAT('$[', n.idx, '].TaskID')) TaskID,
    JSON_EXTRACT(js, CONCAT('$[', n.idx, '].Elapsed')) Elapsed
FROM mytable t
CROSS JOIN (
    SELECT 0 idx 
    UNION ALL SELECT 1 
    UNION ALL SELECT 2 
    UNION ALL SELECT 3
) n
WHERE JSON_EXTRACT(js, CONCAT('$[', n.idx, '].Elapsed')) * 1.0 > 30

注意:在WHERE 子句中,* 1.0 操作用于强制转换为数字。

Demo on DB Fiddle 与您的示例数据:

| TaskID         | Elapsed |
| -------------- | ------- |
| TAS00000012346 | 35      |
| TAS00000012347 | 40      |

【讨论】:

专线小巴,非常感谢。它确实有效。你能解释一下“n.idx”的作用吗? @JNicolls:欢迎! n 是生成数字列表的子查询的别名,idx 是包含数字本身的列。所以n.idx 产生0,然后是1,以此类推。【参考方案2】:

是的,你绝对可以在 mysql 中使用 JSON_EXTRACT() 函数。

让我们获取一个包含 JSON 的表(此处为表 client_services):

+-----+-----------+--------------------------------------+
| id  | client_id | service_values                       |
+-----+-----------+------------+-------------------------+
| 100 |      1000 |  "quota": 1,"data_transfer":160000 |
| 101 |      1000 |  "quota": 2,"data_transfer":800000 |
| 102 |      1000 |  "quota": 3,"data_transfer":70000  |
| 103 |      1001 |  "quota": 1,"data_transfer":97000  |
| 104 |      1001 |  "quota": 2,"data_transfer":1760   |
| 105 |      1002 |  "quota": 2,"data_transfer":1060   |
+-----+-----------+--------------------------------------+

现在假设我们想要所有有 quota>1 的人的 client_id,然后使用这个查询:

SELECT 
    id,client_id,
    JSON_EXTRACT(service_values, '$.quota') AS quota
FROM client_services
WHERE JSON_EXTRACT(service_values, '$.quota') > 1;

因此它会导致:

+-----+-----------+-------+
| id  | client_id | quota |
+-----+-----------+--------
| 101 |      1000 |     2 |
| 102 |      1000 |     3 |
| 104 |      1001 |     2 |
| 105 |      1002 |     2 |
+-----+-----------+-------+

希望这会有所帮助!

【讨论】:

以上是关于MySQL - 搜索 JSON 数据列的主要内容,如果未能解决你的问题,请参考以下文章

在mysql中使用&搜索jsonb数据

PostgreSQL 表中 JSON 数据的搜索列

如何检查 MySQL JSON 列是不是包含 laravel 中的值?

mysql怎么搜索json格式的数据

javascript-如何在 json 字符串上使用正则表达式来搜索 JQuery 中的数据表列?

Mysql Json函数之搜索