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 实际上是如何比较数字数据的,以及进行这种比较的最佳方法是什么。
但是你不是在比较数字数据,对吧。
我可以看到你认为price包含一个数字,但它没有。它包含一个 JSON 值。这可能是一个数字,也可能是文本、数组、对象或包含对象数组的对象,这些对象包含...
您可能会说“但键称为‘价格’,当然它是一个数字”,但这对 PostgreSQL 没有用,特别是当我偷偷地插入一个包含对象数组的对象时,这些对象包含... 1
所以 - 如果你想要一个数字来比较,你需要将它转换为一个数字(t.data->>price)::NUMERIC或将你的目标值转换为 JSON 并让 PostgreSQL 进行基于 JSON 的比较(这可能会做你想做的,也可能不会 - 我不知道JSON 的确切规则是什么)。
1这正是我会做的事情,即使是圣诞节。我是个坏人。