首页/数据/SQL 速查/JSON 路径语法与 jsonpath
函数速查60 条

JSON 路径语法与 jsonpath

路径表达式写法:MySQL 用 '$' 开头的路径字符串;PostgreSQL 运算符用键/数组路径,PG 12+ 的 jsonpath 与 MySQL 风格接近。

SQL 速查数据更新于 2026-10-13

JSON 路径语法是什么

访问 JSON 内部的值得先写对路径。MySQL 从 $ 开始,支持嵌套键 $.a.b、数组下标 $[0]、通配 $[*] 与递归 $**.key、区间 $[1 to 3]、$[last],但不支持过滤表达式。PostgreSQL 有两套:操作符链 payload->'a'->>'b'(-> 返回 json/jsonb,->> 返回文本),以及 SQL/JSON path——jsonb_path_query(payload, '$.items[*] ? (@.price > 100)'),它支持过滤谓词,能力比 MySQL 的路径更强。

基本信息

MySQL 路径以 $ 开头:$.a.b、$[0]、$[*]、$**.name、$[last]
MySQL 特殊键键名含点号、横线或空格时用双引号包住,如 $."order-id"
PostgreSQL 操作符-> 取 json/jsonb,->> 取 text,#> 与 #>> 按路径数组取
PostgreSQL jsonpathjsonb_path_query / jsonb_path_exists / @? / @@,支持过滤器
能力差异MySQL 路径不支持 ? (…) 过滤表达式;PostgreSQL 支持

典型使用场景

  • 从 JSON 列里取单个字段做展示或比较
  • 取数组元素(第一条标签、第一个商品)
  • 递归查找同名键,处理结构不固定的报文
  • 判断某个路径是否存在,用于数据完整性校验
  • 按 JSON 内部条件筛选行(PostgreSQL 的 jsonpath 过滤器)
  • 对比迁移前后取值结果,确认路径语法在新库里同样有效

MySQL 路径写法

MySQL 路径写法
SELECT JSON_EXTRACT(payload, '$.user.name')  AS name_1,    # 取嵌套字段
       payload->'$.user.age'                 AS age_json,  # -> 返回 JSON 类型
       payload->>'$.user.age'                AS age_text,  # ->> 返回字符串
       JSON_EXTRACT(payload, '$.tags[0]')    AS first_tag, # 数组第一个元素
       JSON_EXTRACT(payload, '$**.id')       AS any_id,    # ** 递归查找同名键
       JSON_EXTRACT(payload, '$[last]')      AS last_elem; # 数组最后一个元素

# 键名含特殊字符时用双引号包住
SELECT JSON_EXTRACT(payload, '$."order-id"') AS oid;

PostgreSQL 路径写法

PostgreSQL 路径写法
SELECT payload->'user'->>'name'    AS name_1,   -- 操作符链,末步 ->> 取文本
       payload #> '{user,age}'      AS age_json,-- 路径数组写法等价于 ->->
       payload #>> '{user,tags,0}'  AS first_tag,
       jsonb_path_query_first(payload, '$.user.tags[0]') AS q1
FROM events;

-- 带过滤器的 jsonpath:取价格大于 100 的元素
SELECT jsonb_path_query(payload, '$.items[*] ? (@.price > 100)') FROM events;
SELECT count(*) FROM events WHERE payload @? '$.items[*] ? (@.price > 100)';

能力对照

能力MySQL 8.0PostgreSQL
嵌套键$.a.bpayload->'a'->>'b'
数组下标$.a[0]、$[last]payload->'a'->0
通配与递归*、**jsonpath 的 *、**
区间取值$[1 to 3]用 jsonpath 或数组函数处理
过滤表达式不支持支持 ? (@.price > 10)
返回类型JSON_EXTRACT 返回 JSON,->> 返回字符串-> 返回 json/jsonb,->> 返回文本
MySQL 的旧式路径字符串与 JSON_TABLE、JSON_EXTRACT 共用同一套语法,写错不会报错只会返回 NULL;建议先在真实样本上验证路径,再写进业务语句。
路径取值失败是静默的:返回 NULL 既可能表示键不存在,也可能表示值为 JSON null,两者在业务上含义不同,需要区分时应配合 JSON_CONTAINS_PATH 或 EXISTS PATH 判断。
通配与递归(*、**)返回的是数组或集合,通常还要再迭代取值;这类表达式无法走普通索引,只适合结果集较小、或配合生成列与多值索引使用的场景。

易错点

  • 路径写错返回 NULL 而不报错,被误判为「数据缺失」浪费排查时间
  • 在 MySQL 8.0 里使用过滤表达式($[?(@.x>1)]),语法不支持,语句报错或取不到值
  • -> 与 ->> 混用做比较:前者返回 JSON 类型,与字符串或数字比较的结果不符合预期
  • 键名含点号或横线却没加双引号,路径被解析成多个层级

数据来源与参考

  • MySQL 8.0 Reference Manual · JSON Path Syntax
  • PostgreSQL Documentation · JSON Functions and Operators
​‌‌​​‌​​​‌‌​‌‌‌‌​‌‌​​​‌‌​‌‌‌​​‌‌​​‌​‌‌‌​​‌‌‌​​​‌​‌‌​‌​​‌​‌‌‌​​​‌​‌‌​‌​​‌​‌‌​​​‌‌​‌‌‌​‌​​​‌‌​‌‌‌‌​​‌​‌‌‌​​‌‌​​​‌‌​‌‌​‌‌‌‌​‌‌​‌‌​‌