Postgres функция - Составить массив объектов из нескольких запросов - PullRequest
0 голосов
/ 16 июня 2020

У меня здесь следующий набор данных

create table categories(
    id serial primary key,
    parent_id integer,
    name varchar(255) not null
);
create table entry(
    id serial primary key,
    location_id varchar(255) not null,
    location_string varchar(255) not null
);
create table entry_type(
    id serial primary key,
    name varchar(255) not null,
    category_ids integer[]
);
insert into categories(parent_id,name) values
(null,'a'), (null,'b'),(null,'c'), (1,'d'), (2,'e'), (5,'f');

insert into entry_type(name, category_ids) values
('entry_type_1', '{1}'),('entry_type_2', '{4, 3}'),('entry_type_3', '{5, 6}'),('entry_type_1', '{6}');

insert into entry(location_id, location_string) values
('1/4','a/d'),('2','b'),('5/6','e/f'),('5/6','e/f');

Я выполняю этот запрос:

select
    json_build_object(
            'id', u.id,
            'name', u.name,
            'parent_id', u.parent_id,
      'entry_type', json_agg(json_build_object(
                    'id', ur.id,
                    'name', ur.name
                )),
            'entries', json_agg(json_build_object(
                    'id', en.location_string
                ))
        )
from public.categories u
join public.entry_type ur on u.id = any(ur.category_ids)
join public.entry en on en.location_id like concat(u.id::text, '%')
group by u.id;

(Вот скрипка для всего этого.)

Но я хочу создать функцию Postgres, которая будет возвращать результат (JSON), как описано ниже.

Мне удалось приблизиться к желаемому результату, но я вышел из идеи. в моем запросе я выбираю все категории, но там мне нужно добавить условие, например: parent_id = "function_param", которое может быть NULL, или другой идентификатор / целое число.

[
  {
    "id": "1",
    "name": "a",
    "parent_id": null,
    "entry_types": [
      {
        "id": "18"
      }
    ],
    "entries": [
      {
        "id": "54"
      },
      {
        "id": "22"
      }
    ],
    "entries_count": 2,
    "entry_types_count": 1
  },
  {
    "id": "2",
    "name": "b",
    "parent_id": null,
    "entry_types": [
      {
        "id": "88"
      }
    ],
    "entries": [
      {
        "id": "28"
      }
    ],
    "entries_count": 1,
    "entry_types_count": 1
  }
]

1 Ответ

0 голосов
/ 16 июня 2020

Просто окружите свой запрос json_agg:

SELECT json_agg(j)
FROM (SELECT json_build_object(...) AS j
      FROM public.categories
      ...
     ) AS subq;
...