从 Postgres 中的 JSONB 字段中选择不为空的值

Posted

技术标签:

【中文标题】从 Postgres 中的 JSONB 字段中选择不为空的值【英文标题】:SELECT values which are not null from JSONB field in Postgres 【发布时间】:2016-05-01 07:26:32 【问题描述】:

我无法从 Postgres 9.5 中 JSONB 字段内的属性中选择非空值

SELECT data->>'property' FROM mytable WHERE data->>'property' IS NOT NULL;

我也尝试过使用 NOTNULL。

当我运行其中任何一个时,我都会收到错误 42883。 “错误:运算符不存在。JSONB->>布尔提示:没有运算符与给定名称和参数类型匹配。您可能需要添加显式类型转换。”

【问题讨论】:

你确定你不使用 9.4 吗?在 9.4 中,->> 运算符的优先级低于IS [NOT] NULL(因此您的查询被解析为data ->> ('property' IS NOT NULL))。我现在没有要测试的 9.5 实例,但似乎(来自@Patrick 的回答)这可能是 9.5 中引入的改进。在 9.4 中,最简单的解决方法是使用括号:(data->>'property') IS NOT NULL 确实发生了变化:9.4 与 9.5(->->>(任何其他) 运算符内)。 【参考方案1】:

我很快测试了你的问题,没有发现问题:

patrick@brick:~$ psql -d test
psql (9.5.0)
Type "help" for help.

test=# CREATE TABLE mytable (id serial PRIMARY KEY, data jsonb);
CREATE TABLE
test=# INSERT INTO mytable (data) VALUES
('"ip": "192.168.0.1", "property": "router"'),
('"ip": "127.0.0.1", "property": "localhost"'),
('"ip": "192.168.0.15", "property": null');
INSERT 0 3
test=# SELECT * FROM mytable;
 id |                     data
----+----------------------------------------------
  1 | "ip": "192.168.0.1", "property": "router"
  2 | "ip": "127.0.0.1", "property": "localhost"
  3 | "ip": "192.168.0.15", "property": null
(3 rows)

test=# SELECT data->>'property' FROM mytable WHERE data->>'property' IS NOT NULL;
 ?column?
-----------
 router
 localhost
(2 rows)

请注意,在jsonb 中,NULL 值应在输入时精确指定(如上例所示),而不是在某些引用版本中。如果值不是NULL,而是一个空字符串或类似'<null>'(一个字符串)的东西,那么你应该调整你的测试来寻找它:WHERE data->>'property' = ''。如果是这种情况,您可以考虑使用 jsonb_set() 将这些值设置为真正的 json null

顺便说一句,你也可以这样做:

SELECT data-&gt;&gt;'property' FROM mytable WHERE <b>data-&gt;'property'</b> IS NOT NULL;

即测试jsonbNULL 值,而不是将其转换为text。更高效,当然在更大的桌子上。这显然只适用于真正的nulls。

【讨论】:

很遗憾,我无法在此处发布 JSON,但我可以制作一些 cmets。 1. JSONB 上的其他查询运行良好。 2. 看起来 JSON 的这个特定属性中的大多数数据都定义为 我认为我的 JSON 属性没有按照您发布的方式设置为 null。有没有办法检查空字符串? + 用于提及 -> 而不是文本类型转换 (->>),因为大多数人只是在他们真的不需要开销时复制带有类型转换的示例!【参考方案2】:

首先检查 JSON 密钥是否为空(使用单个 ->),这很重要。

然后检查该值是否为空(使用双 ->>)有一些可能的空值,所以添加检查任何你认为是空的

所以询问的查询变成了。

SELECT data->>'property' 
FROM mytable 
WHERE data->'property' IS NOT NULL
    AND data->>'property' <> ''
    AND data->>'property' <> ''
    AND data->>'property' <> '[]';

【讨论】:

以上是关于从 Postgres 中的 JSONB 字段中选择不为空的值的主要内容,如果未能解决你的问题,请参考以下文章

如何将postgres jsonb字段的属性插入键值表?

Postgres:从匿名jsonb数组元素中删除对象

如何根据postgres的jsonb列的where条件(无本机查询)使用jpa在spring boot中选择数据?

读取 pyspark 数据框中的 jsonb 类型字段? [复制]

Postgres 检查空 JSONB 字段

Postgres:查询多个jsonb字段