Как можно объединить две таблицы, чтобы получить массив json в postgresql? - PullRequest
0 голосов
/ 25 апреля 2020

У меня есть две таблицы в postgresql

Таблица A

id | name | b_codes
---|------|---------
1  | abc  | a,b
2  | def  | null

Таблица B

code | name
-----|------
a    | xx
b    | yy

Как я могу получить эти (точка json массивов):

запрос A.id = 1:

{id: 1, name:'abc', b_codes:[{code: 'a', name: 'xx'}, {code: 'b', name: 'yy'}]}

запрос A. id = 2:

{id: 2, name:'def', b_codes:[]}

или все:

 id | name | codes
 ---|------|----------------------------------------------------
 1  | abc  | [{code: 'a', name: 'xx'}, {code: 'b', name: 'yy'}]
 2  | def  | []

1 Ответ

1 голос
/ 25 апреля 2020

Сначала необходимо нормализовать модель данных, чтобы можно было правильно присоединиться к списку кодов:

select a.id, a.name, x.*
from table_a a
  left join lateral (
    select b.code, b.name
    from unnest(string_to_array(a.b_codes, ',')) as c(code)
       join table_b b on b.code = c.code
  ) as x on true
; 

Это возвращает следующий результат:

id | name | code | name
---+------+------+-----
 1 | abc  | a    | xx  
 1 | abc  | b    | yy  
 2 | def  |      |     

Коды могут быть агрегированы непосредственно в производной таблице (подзапрос):

select a.id, a.name, coalesce(x.codes, '[]') as codes
from table_a a
  left join lateral (
    select jsonb_agg(jsonb_build_object('code', b.code, 'name', b.name)) as codes
    from unnest(string_to_array(a.b_codes, ',')) as c(code)
       join table_b b on b.code = c.code
  ) as x on true
;  

coalesce() необходим для получения пустого массива для id = 2, в противном случае столбец codes из производной таблицы будет null.

Теперь его можно преобразовать в JSON значения:

select jsonb_build_object('id', a.id, 'name', a.name, 'b_codes', coalesce(x.codes, '[]'))
from table_a a
  left join lateral (
    select jsonb_agg(jsonb_build_object('code', b.code, 'name', b.name)) as codes
    from unnest(string_to_array(a.b_codes, ',')) as c(code)
       join table_b b on b.code = c.code
  ) as x on true
;  

Онлайн-пример

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...