PostgreSQL Объединить данные в одну строку - PullRequest
0 голосов
/ 11 сентября 2018

С помощью следующего SQL-запроса, в который я хочу добавить массив объектов JSON, содержащий данные из другой таблицы, на основе массива posts.liked_by:

SELECT 
  p.id, 
  p.author, 
  p.content, 
  u2.id, 
  u2.username, 
  p.liked_by AS likedby
FROM posts p
INNER JOIN users u1 
    ON p.author = u1.id
LEFT JOIN users u2 
    ON u2.id = ANY(p.liked_by)

я получаю ожидаемый результат

╔════╤════════╤═════════════╤══════════╤═════════╗
║ id │ author │ content     │ username │ likedby ║
╠════╪════════╪═════════════╪══════════╪═════════╣
║ 1  │ 1      │ Lorem Ipsum │ John Doe │ {1, 2}  ║
╚════╧════════╧═════════════╧══════════╧═════════╝

Теперь я хотел бы изменить столбец likedby, чтобы он представлял собой массив объектов с пользовательскими данными в соответствии с чем-то вроде этого:

+----+--------+-------------+----------+-----------------------------------------------------------------+
| id | author | content     | username | liked_by                                                        |
+----+--------+-------------+----------+-----------------------------------------------------------------+
| 1  | 1      | Lorem Ipsum | John Doe | [{id: 1, username: "John Doe"}, {id: 2, username: "Sam Smith"}] |
+----+--------+-------------+----------+-----------------------------------------------------------------+

с данными таблицы сообщений, структурированными как

+----+--------+-------------+-----------+-----------+
| id | author | content     | author_id | liked_by  |
+----+--------+-------------+-----------+-----------+
| 1  | 1      | lorem ipsum | 1         | {1, 2, 3} |
+----+--------+-------------+-----------+-----------+

, и таблицей пользователей, структурированными как

+----+----------+
| id | username |
+----+----------+
| 1  | John Doe |
+----+----------+

Как бы я поступил так?

Ответы [ 2 ]

0 голосов
/ 11 сентября 2018

для получения агрегированных имен пользователей для столбца liked_by, вы можете использовать подзапрос с функциями jsonb_agg() и jsonb_build_object():

SELECT posts.*, "user".username as author_name,  
    (SELECT jsonb_agg(jsonb_build_object("user".id, "user".username)) FROM "user" where "user".id = any(posts.liked_by)  )
FROM posts
INNER JOIN "user"
ON posts.author_id = "user".id

http://rextester.com/KMEY13984

0 голосов
/ 11 сентября 2018

Работает с явным объединением (кстати, смешивать и сопоставлять не очень хорошо):

SELECT
    ...
FROM posts p
INNER JOIN users u1 
    ON p.author = u1.id
LEFT JOIN users u2 
    ON u2.id = ANY(p.liked_by)

И почему, из документации postgres :

... JOIN связывает более тесно, чем запятая. Например, ОТ T1 CROSS JOIN T2 INNER JOIN Состояние T3 ON не совпадает с FROM T1, T2 INNER JOIN T3 ON, потому что условие может ссылаться на T1 в первый случай, но не второй.

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