使用MySQL JSON查询筛选嵌套字段的值方式

 更新时间:2026年01月08日 10:42:35   作者:当年明月思古今  
本文介绍了如何在MySQL中查询JSON字段中的特定数据,通过使用JSON_EXTRACT和JSON_UNQUOTE函数,可以方便地从嵌套的JSON结构中提取所需的信息,此外,还讨论了性能优化和数据规范化建议,以提高查询效率

在日常开发中,随着项目需求的不断复杂化,许多表字段可能会存储 JSON 格式的数据。

例如,我们有一张site_device表,其中有一个名为detail的字段,保存了设备的详细信息。这些信息存储为 JSON 数据,如下所示:

{
  "deviceType": "ammeter",
  "techParams": {
    "name": "202501241556",
    "deviceNo": "202501241556",
    "gatewayNo": "1829047495952388098",
    "ownership": "top",
    "dataReport": "1"
  },
  "deviceBrand": "HUAWEI",
  "deviceModel": "test",
  "modelConfigId": "1871021778273325058"
}

我们想要查询出 ownershiptop 的设备。ownership 字段嵌套在 techParams 中,因此我们需要使用 MySQL 提供的 JSON 函数来实现查询。

1. 理解 JSON 数据的层级结构

在这个例子中,JSON 的结构可以分解为:

  • deviceType:在 JSON 顶层。
  • techParams:是一个嵌套对象,里面包含了 ownership 等字段。
  • ownership:目标字段,位于 techParams 内。

我们需要从 detail 中提取出 techParams.ownership 的值。

2. 使用 MySQL JSON 查询函数

MySQL 提供了一系列函数用于处理 JSON 数据:

  • JSON_EXTRACT(json_doc, path):从 JSON 中提取值。
  • JSON_UNQUOTE(json_val):去掉 JSON 提取值的引号,返回纯文本。

对于本例来说,我们可以用以下语句来筛选出 ownershiptop 的记录:

SELECT *
FROM site_device
WHERE JSON_UNQUOTE(JSON_EXTRACT(detail, '$.techParams.ownership')) = 'top';

语法解释

JSON_EXTRACT(detail, '$.techParams.ownership')

提取 detailtechParams 对象内的 ownership 值。

JSON_UNQUOTE(...)

去掉 JSON 提取结果的引号,使其变为普通字符串。

WHERE ... = 'top'

筛选出 ownership 值等于 top 的记录。

3. 示例数据和运行结果

假设 site_device 表中的数据如下:

iddetail
1{"deviceType": "ammeter", "techParams": {"ownership": "top", "dataReport": "1"}, "deviceBrand": "HUAWEI"}
2{"deviceType": "ammeter", "techParams": {"ownership": "bottom", "dataReport": "1"}, "deviceBrand": "HUAWEI"}
3{"deviceType": "ammeter", "techParams": {"ownership": "top", "dataReport": "1"}, "deviceBrand": "HUAWEI"}

运行查询后,结果为:

iddetail
1{"deviceType": "ammeter", "techParams": {"ownership": "top", "dataReport": "1"}, "deviceBrand": "HUAWEI"}
3{"deviceType": "ammeter", "techParams": {"ownership": "top", "dataReport": "1"}, "deviceBrand": "HUAWEI"}

4. 注意事项

JSON 路径表达式 $

JSON 路径表达式 $ 表示 JSON 的根,嵌套字段用 . 分隔。例如:$.techParams.ownership

性能优化

如果数据量较大,可以通过为 JSON 字段创建虚拟列(Generated Column)并加索引来提升查询性能。

ALTER TABLE site_device
ADD COLUMN ownership VARCHAR(50) GENERATED ALWAYS AS (JSON_UNQUOTE(JSON_EXTRACT(detail, '$.techParams.ownership'))) STORED,
ADD INDEX idx_ownership (ownership);

数据规范化

如果 JSON 数据中的字段经常被查询,考虑将这些字段拆分到独立的数据库列中,以提高查询效率。

5. 总结

MySQL 提供了强大的 JSON 查询功能,使得我们可以方便地处理结构化的 JSON 数据。在本文中,我们通过 JSON_EXTRACTJSON_UNQUOTE 函数,成功筛选出了目标字段值为特定值的记录。同时,结合性能优化建议,可以让你的 JSON 查询更高效。

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

相关文章

  • MySQL5.7不停业务将传统复制变更为GTID复制的实例

    MySQL5.7不停业务将传统复制变更为GTID复制的实例

    下面小编就为大家带来一篇MySQL5.7不停业务将传统复制变更为GTID复制的实例。小编觉的挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-03-03
  • mysql默认编码为UTF-8 通过修改my.ini实现方法

    mysql默认编码为UTF-8 通过修改my.ini实现方法

    这篇文章主要介绍了mysql默认编码为UTF-8 通过修改my.ini实现方法的相关资料,为了防止出现乱码,Latin1是不支持汉字的,所以要将其改为UTF-8或GBK,需要的朋友可以参考下
    2017-01-01
  • MySQL如何优化查询速度

    MySQL如何优化查询速度

    这篇文章主要介绍了MySQL如何优化查询速度,帮助大家提升自己的数据库性能,感兴趣的朋友可以了解下
    2020-08-08
  • mysql触发器(Trigger)简明总结和使用实例

    mysql触发器(Trigger)简明总结和使用实例

    这篇文章主要介绍了mysql触发器(Trigger)简明总结和使用实例,需要的朋友可以参考下
    2014-04-04
  • MySQL使用EXISTS检查记录是否存在的详细过程

    MySQL使用EXISTS检查记录是否存在的详细过程

    EXISTS是SQL中用于检查子查询是否返回至少一条记录的运算符,它通常用于测试是否存在满足特定条件的记录,从而在主查询中进行相应操作,本文给大家介绍MySQL使用EXISTS检查记录是否存在,感兴趣的朋友一起看看吧
    2025-08-08
  • MySql数据库基础之分组查询详解

    MySql数据库基础之分组查询详解

    这篇文章主要介绍了mysql按照时间分组查询的语句,非常实用,sql语句简单易懂,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2022-09-09
  • MySQL和Redis之间的存储区别

    MySQL和Redis之间的存储区别

    MySQL是一种关系型数据库,而Redis是一种键值对存储数据库,虽然它们都是用来存储和管理数据的,但是它们在很多方面都有不同,本文就给大家详细介绍一下MySQL和Redis之间的存储区别,感兴趣的同学可以参考一下
    2023-06-06
  • MySQL COUNT(*)性能原理详解

    MySQL COUNT(*)性能原理详解

    这篇文章主要介绍了MySQL COUNT(*)性能原理详解,文章围绕主题展开详细的内容介绍,具有一定的参考价值,需要的小伙伴可以参考一下
    2022-08-08
  • mysql中InnoDB事务隔离的记录锁、间隙锁和临键锁

    mysql中InnoDB事务隔离的记录锁、间隙锁和临键锁

    mysql中InnoDB默认的事务隔离级别为可重复读(Repeated Read, RR),我们当下的所有介绍都是基于这个隔离级别为前提的,记录锁锁定索引关联的具体记录,间隙锁锁定间隔,防止间隔中被其他事务插入,临键锁锁定索引记录+间隔,防止幻读
    2023-12-12
  • MySQL5.73 root用户密码修改方法及ERROR 1193、ERROR1819与ERROR1290报错解决

    MySQL5.73 root用户密码修改方法及ERROR 1193、ERROR1819与ERROR1290报错解决

    这篇文章主要给大家介绍了关于MySQL5.73 root用户密码修改方法及ERROR 1193、ERROR1819与ERROR1290:... running with --skip-...报错的解决方法,文中通过图文将解决的步骤介绍的非常详细,需要的朋友可以参考下
    2023-02-02

最新评论