postgres STRING_AGG () возвращает дубликаты? - PullRequest
0 голосов
/ 12 апреля 2020

Я видел несколько похожих постов, в которых запрашивался совет для получения отличных результатов от запроса. Это можно решить с помощью подзапроса, но столбец, который я собираю image_name, уникален image_name VARCHAR(40) NOT NULL UNIQUE. Я не верю, что это должно быть ненужным.

Это данные в таблице spot_images

spotdk=# select * from spot_images;
 id | user_id | spot_id |              image_name              
----+---------+---------+--------------------------------------
  1 |       1 |       1 | 81198013-e8f8-4baa-aece-6fbda15a0498
  2 |       1 |       1 | 21b78e4e-f2e4-4d66-961f-83e5c28d69c5
  3 |       1 |       1 | 59834585-8c49-4cdf-95e4-38c437acb3c1
  4 |       1 |       1 | 0a42c962-2445-4b3b-97a6-325d344fda4a
(4 rows)
SELECT Round(Avg(ratings.rating), 2) AS rating, 
       spots.*, 
       String_agg(spot_images.image_name, ',') AS imageNames
FROM   spots 
       FULL OUTER JOIN ratings 
                    ON ratings.spot_id = spots.id 
       INNER JOIN spot_images 
               ON spot_images.spot_id = spots.id 
WHERE  spots.id = 1 
GROUP  BY spots.id; 

Это результат строки изображений:

81198013-e8f8-4baa-aece-6fbda15a0498,
21b78e4e-f2e4-4d66-961f-83e5c28d69c5,
59834585-8c49-4cdf-95e4-38c437acb3c1,
0a42c962-2445-4b3b-97a6-325d344fda4a,
81198013-e8f8-4baa-aece-6fbda15a0498,
21b78e4e-f2e4-4d66-961f-83e5c28d69c5,
59834585-8c49-4cdf-95e4-38c437acb3c1,
0a42c962-2445-4b3b-97a6-325d344fda4a,
81198013-e8f8-4baa-aece-6fbda15a0498,
21b78e4e-f2e4-4d66-961f-83e5c28d69c5,
59834585-8c49-4cdf-95e4-38c437acb3c1,
0a42c962-2445-4b3b-97a6-325d344fda4a

Я не добавил разрывов строк, я добавил их для наглядности.

Что я должен сделать, чтобы получить одно имя изображения каждый раз?

Ответы [ 2 ]

2 голосов
/ 12 апреля 2020

Если вам не нужны дубликаты, используйте DISTINCT:

   String_agg(distinct spot_images.image_name, ',') AS imageNames
0 голосов
/ 12 апреля 2020

Вероятно, есть несколько строк в ratings, которые соответствуют указанным spot, и , несколько строк в spot_images, которые также соответствуют данному sport. В результате строки дублируются.

Один из способов избежать этого - агрегирование в подзапросах:

SELECT r.avg_raging
       s.*, 
       si.image_names
FROM   spots s
       FULL OUTER JOIN (
           SELECT spot_id, Round(Avg(ratings.rating), 2) avg_rating
           FROM ratings
           GROUP BY spot_id
       ) r ON r.spot_id = s.id
       INNER JOIN (
           SELECT spot_id, string_agg(spot_images.image_name, ',') image_names
           FROM spot_images
           GROUP BY spot_id
       ) si ON si.spot_id = s.id 
WHERE  s.id = 1 

На самом деле может быть более эффективным, чем внешнее агрегирование .

Примечание: трудно увидеть, не видя ваших данных, но я не уверен, что вам действительно нужен FULL JOIN здесь. A LEFT JOIN на самом деле может быть тем, что вы хотите.

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