【问题标题】:JSONB nested array query - check existence of attributeJSONB 嵌套数组查询 - 检查属性是否存在
【发布时间】:2019-06-11 13:08:42
【问题描述】:

我想使用 SQL 检查 JSONB 列中是否存在属性。

使用这个我可以检查属性是否等于值:

SELECT count(*) AS "count" FROM "table" WHERE column->'node' @> '[{"Attribute":"value"}]'

我用什么语法来检查属性的存在?

【问题讨论】:

    标签: sql json postgresql jsonb


    【解决方案1】:

    通常你会检查 null:

    SELECT count(*) AS "count" FROM "table" 
    WHERE column->'node'->'Attribute' is not null
    

    【讨论】:

      【解决方案2】:

      ? 操作符的意思是Does the string exist as a top-level key within the JSON value? 但是,你想检查一个key是否存在于嵌套的json对象数组中,所以不能直接使用操作符。您必须取消嵌套数组。

      样本数据:

      create table my_table(id serial primary key, json_column jsonb);
      insert into my_table (json_column) values
          ('{"node": [{"Attribute":"value"}, {"other key": 0}]}'),
          ('{"node": [{"Attribute":"value", "other key": 0}]}'),
          ('{"node": [{"Not Attribute":"value"}]}');
      

      在横向连接中使用jsonb_array_elements() 来找出键是否存在于数组的任何元素中:

      select
          id,
          value,
          value ? 'Attribute' as key_exists_in_object
      from my_table 
      cross join jsonb_array_elements(json_column->'node')
      
       id |                 value                  | key_exists_in_object 
      ----+----------------------------------------+----------------------
        1 | {"Attribute": "value"}                 | t
        1 | {"other key": 0}                       | f
        2 | {"Attribute": "value", "other key": 0} | t
        3 | {"Not Attribute": "value"}             | f
      (4 rows)
      

      但这并不是您所期望的。您需要汇总数组的结果:

      select
          id,
          json_column->'node' as array,
          bool_or(value ? 'Attribute') as key_exists_in_array
      from my_table 
      cross join jsonb_array_elements(json_column->'node')
      group by id
      order by id
      
       id |                   array                    | key_exists_in_array 
      ----+--------------------------------------------+---------------------
        1 | [{"Attribute": "value"}, {"other key": 0}] | t
        2 | [{"Attribute": "value", "other key": 0}]   | t
        3 | [{"Not Attribute": "value"}]               | f
      (3 rows)
      

      嗯,这看起来有点复杂。您可以更轻松地使用该功能:

      create or replace function key_exists_in_array(key text, arr jsonb)
      returns boolean language sql immutable as $$
          select bool_or(value ? key)
          from jsonb_array_elements(arr)
      $$;
      
      select
          id,
          json_column->'node' as array,
          key_exists_in_array('Attribute', json_column->'node')
      from my_table 
      
       id |                   array                    | key_exists_in_array 
      ----+--------------------------------------------+---------------------
        1 | [{"Attribute": "value"}, {"other key": 0}] | t
        2 | [{"Attribute": "value", "other key": 0}]   | t
        3 | [{"Not Attribute": "value"}]               | f
      (3 rows)
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2013-03-31
        • 2014-02-17
        • 1970-01-01
        • 2023-04-07
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-06-13
        相关资源
        最近更新 更多