Для моей проблемы у нас есть схема, в которой на одной фотографии есть много тегов, а также много комментариев. Поэтому, если у меня есть запрос, где я хочу все комментарии и теги, он будет умножать строки вместе. Поэтому, если у одной фотографии есть 2 тега и 13 комментариев, я получаю 26 строк для одной фотографии:
SELECT
tag.name,
comment.comment_id
FROM
photo
LEFT OUTER JOIN comment ON comment.photo_id = photo.photo_id
LEFT OUTER JOIN photo_tag ON photo_tag.photo_id = photo.photo_id
LEFT OUTER JOIN tag ON photo_tag.tag_id = tag.tag_id
Это прекрасно для большинства вещей, но это означает, что если я GROUP BY
, а затем json_agg(tag.*)
, я получаю 13 копий первого тега и 13 копий второго тега.
SELECT json_agg(tag.name) as tags
FROM
photo
LEFT OUTER JOIN comment ON comment.photo_id = photo.photo_id
LEFT OUTER JOIN photo_tag ON photo_tag.photo_id = photo.photo_id
LEFT OUTER JOIN tag ON photo_tag.tag_id = tag.tag_id
GROUP BY photo.photo_id
Вместо этого я хочу массив, который является только "пригородным" и "городом", например:
[
{"tag_id":1,"name":"suburban"},
{"tag_id":2,"name":"city"}
]
Я мог бы json_agg(DISTINCT tag.name)
, но это создаст массив имен тегов, когда я хочу, чтобы вся строка была json. Я хотел бы json_agg(DISTINCT ON(tag.name) tag.*)
, но это недействительный SQL, по-видимому.
Как я могу моделировать DISTINCT ON
внутри агрегатной функции в Postgres?