运算符不存在:json @>未知

时间:2019-05-22 05:46:47

标签: postgresql

我有下表,我想要布局名称为userid ='user-1'和gridname ='RT'的

| userid |                                                                              defaultdata |
|--------|------------------------------------------------------------------------------------------|
| user-1 | [{"gridname":"RT", "layoutname":"layout-1"},{"gridname":"RT2", "layoutname":"layout-2"}] |
| user-2 | [{"gridname":"RT", "layoutname":"layout-3"},{"gridname":"RT2", "layoutname":"layout-2"}] |

到目前为止,我已经尝试过了。

 SELECT userid, obj.value->>'gridname' AS gridname
 FROM   col.userdefault t
 JOIN   lateral jsonb_array_elements(t.defaultdata::jsonb) obj(value) ON 
 obj.value->>'_gridname' = 'RT'
 WHERE  defaultdata @> '[{"_gridname":"RT"}]';

但无法正常工作并出现以下错误:

ERROR:  operator does not exist: json @> unknown
LINE 4: WHERE  defaultdata @> '[{"_gridname":"RT"}]::jsonb';
                           ^
HINT:  No operator matches the given name and argument types. You might need to add explicit type casts.
SQL state: 42883
Character: 198

2 个答案:

答案 0 :(得分:3)

demo: db<>fiddle

要获取gridname的值,您必须扩展数组,然后检查其每个元素:

SELECT
    userid,
    elems ->> 'layoutname' AS layoutname                  -- 3
FROM
    mytable,
    json_array_elements(defaultdata) elems                -- 1
WHERE userid = 'user-1' AND elems ->> 'gridname' = 'RT'   -- 2
  1. json_array_elements()将JSON数组扩展为每个元素一行。
  2. 可以检查扩展元素的相关值,并可以用作过滤器
  3. 之后,您就可以获取数据

我和@>比较器一起玩。我发现您的方法还不错(假设您将使用jsonb类型而不是json类型)。 @>可以完成工作:

SELECT 
    *
FROM mytable
WHERE defaultdata @> '[{"gridname":"RT"}]'

demo

这将返回整个数组,而不仅是包含此数组的元素。这意味着如果您以这种方式使用它,它将返回其中任何元素包含此部分的数组。

要获得一个元素,您需要将其扩展为已经完成的工作。唯一的问题是您没有在WHERE子句中使用扩展元素,而是使用原始数据。使用扩展的元素将导致以下查询:

SELECT 
    userid,
    elems ->> 'layoutname' AS layoutname
FROM mytable,
    jsonb_array_elements(defaultdata) elems
WHERE userid = 'user-1' AND elems @> '{"gridname":"RT"}'

demo

这很好!

答案 1 :(得分:3)

@>不存在json运算符,仅jsonb不存在。

您可以使用显式类型转换来消除即时错误,如错误消息所示:

WHERE defaultdata::jsonb @> '...'

再往前看,我想知道json是否是适合您的数据类型。对于要在数据库内部有效处理的数据,jsonb更好。