Найти строки на основе вложенного ключа в массиве jsonb - PullRequest
1 голос
/ 15 октября 2019

У меня есть столбец jsonb в Postgres 9.6, который содержит массивы JSON следующей формы:

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

Я хочу найти всех пользователей, которые зарегистрировались в course-1 или course-12 содин запрос. То есть пользователи, у которых есть course-1 или course-12 в объекте courses для любой из записей в их массиве jsonb.

Я пробовал несколько вещей, таких как следующие,что, конечно, не работает:

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

Есть предложения о том, как решить эту проблему? Спасибо!

1 Ответ

1 голос
/ 15 октября 2019

Вы можете использовать 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

Демонстрация на 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-1 и course-12. Третий массив не совпадает.

...