根据jsonb数组中的嵌套键查找行

时间:2019-10-14 22:02:50

标签: postgresql jsonb

我在Postgres 9.6中有一个jsonb列,其中包含以下形式的JSON数组:

[
  {
    "courses": { "course-1": { "graduated": false }, "course-5": { "graduated": true } }
  },
  {
    "courses": { "course-6": { "graduated": false } }
  }
]

我想找到一个查询就注册了course-1course-12的所有用户。也就是说,course-1数组中任何条目的对象都在course-12对象中拥有coursesjsonb的用户。

我尝试了很多类似以下的操作,但是这些操作当然不起作用:

select enrollment_info from users where (enrollment_info @> '["courses" ?| array['course-1', 'course-12']]')

有关如何解决此问题的任何建议?谢谢!

1 个答案:

答案 0 :(得分:1)

您可以使用jsonb_array_elements对数组进行嵌套,然后检查是否存在至少一个搜索到的键:

select enrollment_info
from users,
jsonb_array_elements(enrollment_info) courses
where 
    courses->'courses'->'course-1' is not null
    or courses->'courses'->'course-12' is not null

Demo on DB Fiddle

with users as (
    select 
    '[ 
        { "courses": { "course-1": { "graduated": false }, "course-5": { "graduated": true } }},
        { "courses": { "course-6": { "graduated": false } } }
    ]'::jsonb enrollment_info
    union all select 
    '[ 
        { "courses": { "course-12": { "graduated": false }, "course-5": { "graduated": true } }}
    ]'::jsonb
    union all select 
    '[ 
        { "courses": { "course-4": { "graduated": false } }}
    ]'::jsonb
)
select enrollment_info
from users,
jsonb_array_elements(enrollment_info) courses
where 
    courses->'courses'->'course-1' is not null
    or courses->'courses'->'course-12' is not null
| enrollment_info                                                                                                                     |
| :---------------------------------------------------------------------------------------------------------------------------------- |
| [{"courses": {"course-1": {"graduated": false}, "course-5": {"graduated": true}}}, {"courses": {"course-6": {"graduated": false}}}] |
| [{"courses": {"course-5": {"graduated": true}, "course-12": {"graduated": false}}}]                                                 |

前两个数组匹配,因为它们分别包含course-1course-12。第三个数组不匹配。