用->还是->>取决于需求:->返回JSON类型,支持链式提取;->>返回text类型,适合直接比较或显示。例如info->'name'返回" Alice "(JSON),info->>'name'返回Alice(text)。

查 JSON 字段的某个键值用 -> 还是 ->>?
取决于你要的是「可继续提取的 JSON 对象」还是「直接能比较/显示的文本」。比如字段叫 info,存的是 {"name": "Alice", "tags": ["vip", "beta"]}:
-
info->'name'返回"Alice"(带双引号的 JSON 字符串,类型仍是jsonb) -
info->>'name'返回Alice(纯文本,类型是text,可直接用于WHERE name = 'Alice'或ORDER BY)
常见错误:在 WHERE 里混用——WHERE info->>'name'->>'age' 会报错,因为 ->> 已经吐出文本,不能再接 ->。要多层取,必须用 -> 开头,最后一层才用 ->>,例如:info->'user'->>'id'。
查 JSON 数组里的第 N 个元素怎么写?
数组索引从 0 开始,-> 和 ->> 同样适用:
-
info->0:返回数组第一个元素(JSON 格式),支持继续链式操作,比如info->0->>'status' -
info->>0:返回第一个元素的文本值,比如数组是["a", "b", "c"],结果就是a(无引号)
注意:如果数组为空或索引越界,-> 返回 NULL(JSON 类型),->> 也返回 NULL(text 类型),不会报错,但需在业务逻辑中处理空值。
嵌套太深时,#> 和 #>> 比链式更稳
比如要取 {"a": {"b": {"c": 123}}} 里的 c 值,链式写法是 info->'a'->'b'->>'c';路径写法是 info#>>'{a,b,c}'。后者优势明显:
- 少写一堆
->,不易漏括号或引号 - 路径是
text[]类型,支持变量拼接(如用array['a', col_name]动态构造) - 对含数字键或特殊字符的 key 更安全(比如
{ "0": { "foo-bar": true } },用->'0'->'foo-bar'会因连字符报错,而#>>'{0,"foo-bar"}'可正常工作)
但注意:#> 和 #>> 的路径参数必须是字面量数组或表达式,不能是普通字符串列——info#>>path_col 会报错,得写成 info#>>(string_to_array(path_col, ','))。
WHERE 条件里查 JSON 字段容易忽略类型和 NULL
直接用 info->>'status' = 'active' 看似没问题,但有三个坑:
- 如果
status键不存在,->>返回NULL,而NULL = 'active'结果是UNKNOWN,不是FALSE,所以该行被过滤掉——这通常符合预期,但得心里有数 - 如果字段类型是
json(非jsonb),某些旧版本可能不走索引,建议统一用jsonb - 想查“键存在且值为某值”,别只写
info ? 'status'(只判断键存在),应组合:info ? 'status' AND info->>'status' = 'active'
最易被跳过的点:JSON 字段本身为 NULL 时,所有 ->/->> 操作都返回 NULL,不会报错,但 WHERE 中的等值判断会失效——务必先加 info IS NOT NULL 显式过滤。


















