повторяющиеся строки в json_agg () в запросе с 2 боковыми объединениями - PullRequest
0 голосов
/ 27 апреля 2018

У меня странный результат при выполнении бокового соединения по запросу

У меня есть следующая структура таблицы

task->id 
comment -> id , taskId, comment
tasklink -> taskId, type, userid

с одной записью задачи (id 10), 1 записью комментария ("row1", "тестовый комментарий") и 5 ​​записями ссылки на задание (все с taskid 10)

Я ожидал этого запроса

select task.id,
       json_agg(json_build_object('id',c.id, 'user',c.comment)) as comments,
       json_agg(json_build_object('type',b.type, 'user',b.userid)) as users

  FROM task 
  left join lateral (select c.* from comment c where task.id = c.taskid) c on true
  left join lateral (select b.* from taskuserlink b where task.id = b.taskid) b on true

  where task.id = 10    
  GROUP BY task.id ;

чтобы вернуть

id | comments                                   | users
---------------------------------------------------------------------
10  "[{"id":"row1","user":"a test comment"}]"   "[{"type":"updatedBy","user":1},"type":"closedBy","user":5},"type":"updatedBy","user":5},"type":"createdBy","user":5},{"type":"ownedBy","user":5}]"

вместо этого я получил это

id | comments                                                                                                                                                                                           | users
10  "[{"id":"row1","user":"a test comment"},{"id":"row1","user":"a test comment"},{"id":"row1","user":"a test comment"},{"id":"row1","user":"a test comment"},{"id":"row1","user":"a test comment"}]"   "[{"type":"updatedBy","user":1},{"type":"closedBy","user":5},{"type":"updatedBy","user":5},{"type":"createdBy","user":5},{"type":"ownedBy","user":5}]"

т. Е. Для каждой строки link строка comment дублируется

Мне кажется, что я упускаю что-то действительно очевидное, но поскольку я только начал использовать Postgres (и sql), я немного озадачен

Буду признателен за некоторые указания о том, где я иду не так

1 Ответ

0 голосов
/ 27 апреля 2018

Перемещение агрегатов в подзапросы:

select id, comments, users
from task t
left join lateral (
    select json_agg(json_build_object('id',c.id, 'user',c.comment)) as comments
    from comment c
    where t.id = c.taskid
    ) c on true
left join lateral (
    select json_agg(json_build_object('type',b.type, 'user',b.userid)) as users
    from taskuserlink b 
    where t.id = b.taskid 
    ) b on true

DbFiddle.

...