@Gahoy

Как правильно собирать данные с разных таблиц БД?

У меня есть такие таблицы в БД:

640a12080a1dd888467871.jpeg

Как мне получить такую структуру данных из sql запроса ?

export type Author = {
  account_id: number;
  first_name: string;
  last_name: string;
}

export type Posts = {
  post_id: number;
  body: string;
  author: Author;
}


ps: так как данные находятся в разных таблицах, получается что нужно сделать сначала один запрос к базе (получить посты), потом второй (получить авторов), и далее уже соединять их в JavaScript, или можно как-то получить и через запрос SQL такую структуру ?

pss: там еще комментарии нужно получить, я до них еще не добрался.
  • Вопрос задан
  • 178 просмотров
Решения вопроса 1
erge
@erge
Примус починяю
Для построения такого JSON на SQL вам нужны функции json_agg() / json_build_object(), далее обычные запросы с объединениями и группировкой.

Пример как собрать JSON author
SELECT json_build_object(
    'account_id', id,
    'first_name', first_name,
    'last_name', last_name
  ) AS author
  FROM accounts

post собирается как
json_build_object(
    'post_id', p.id,
    'body', p.body,
    'author', json_build_object(
      'account_id', a.id,
      'first_name', a.first_name,
      'last_name', a.last_name
    )
  )
при объединении таблиц posts и accounts
через json_agg собираем в массив
SELECT json_agg(json_build_object(
    'post_id', p.id,
    'body', p.body,
    'author', json_build_object(
      'account_id', a.id,
      'first_name', a.first_name,
      'last_name', a.last_name
    )
  )) AS posts
  FROM posts p
  JOIN accounts a ON a.id = p.author_id

комментарии аналогично, но с группировкой по постам - post_id
SELECT json_agg(json_build_object(
    'comment_id', c.id,
    'body', c.body,
    'author', json_build_object(
      'account_id', a.id,
      'first_name', a.first_name,
      'last_name', a.last_name
    )
  )) AS comments
  FROM comments c
  JOIN accounts a ON a.id = c.author_id
  GROUP BY post_id

далее объединяем комментарии с постами через post_id = id
для удобства комментарии вынес в CTE (общее табличное выражение)
WITH cmts AS (
SELECT json_agg(json_build_object(
    'comment_id', c.id,
    'body', c.body,
    'author', json_build_object(
      'account_id', a.id,
      'first_name', a.first_name,
      'last_name', a.last_name
    )
  )) AS comments,
  post_id
  FROM comments c
  JOIN accounts a ON a.id = c.author_id
  GROUP BY post_id
)
SELECT json_agg(json_build_object(
    'post_id', p.id,
    'body', p.body,
    'author', json_build_object(
      'account_id', a.id,
      'first_name', a.first_name,
      'last_name', a.last_name
    ),
    'comments', COALESCE(c.comments, '[]')
  )) AS "posts with comments"
  FROM posts p
  JOIN accounts a ON a.id = p.author_id
  LEFT JOIN cmts c ON c.post_id = p.id


см. пример sqlfiddle
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы