如何比较 PostgreSQL JSONB 中的数字

use*_*168 4 database postgresql

我在使用jsonb类型时遇到了奇怪的情况。

预期行为


使用短jsonb结构:

{"price": 99.99}
Run Code Online (Sandbox Code Playgroud)

我写了这样的查询:

 SELECT * FROM table t WHERE t.data->price > 90.90
Run Code Online (Sandbox Code Playgroud)

它失败并出现operator does not exist: jsonb > numeric与 text ( ->>)相同的错误operator does not exist: text > numeric

然后我写了很多资源中提到的比较:

SELECT * FROM table t WHERE (t.data->>price)::NUMERIC > 90.90
Run Code Online (Sandbox Code Playgroud)

它按预期工作。

奇怪的是:


SELECT * FROM table t WHERE t.data->price > '90.90';
Run Code Online (Sandbox Code Playgroud)

有点奇怪,但上面的查询工作正常。

解释: Filter: ((data -> 'price'::text) > '90.90'::jsonb)

但是,如果我将jsonb值更改text 为:{"price": "99.99"} 不再有结果 - 空。

问题:PostgreSQL 实际上是如何比较数字数据的,以及进行这种比较的最佳方法是什么。

Ric*_*ton 9

但是你不是在比较数字数据,对吧。

我可以看到你认为price包含一个数字,但它没有。它包含一个 JSON 值。这可能是一个数字,也可能是文本、数组、对象或包含对象数组的对象,这些对象包含...

您可能会说“但键称为‘价格’,当然它是一个数字”,但这对 PostgreSQL 没有用,特别是当我偷偷地插入一个包含对象数组的对象时,这些对象包含... 1

所以 - 如果你想要一个数字来比较,你需要将它转换为一个数字(t.data->>price)::NUMERIC或将你的目标值转换为 JSON 并让 PostgreSQL 进行基于 JSON 的比较(这可能会做你想做的,也可能不会 - 我不知道JSON 的确切规则是什么)。


1这正是我会做的事情,即使是圣诞节。我是个坏人。