Как объединить несколько значений в этом запросе postgresql?

#postgresql

#postgresql

Вопрос:

Это мой запрос:

 SELECT "vehicle"."id",
       "vehicle"."description",
       "tag"."id" AS "tag_id", 
       "tag"."name" AS "tag_name"
FROM "vehicle" 
INNER JOIN "vehicle_tag_pivot" ON "vehicle"."id" = "vehicle_tag_pivot"."vehicle_id" 
INNER JOIN "tag" ON "vehicle_tag_pivot"."tag_id" = "tag"."id" 

WHERE "tag"."name" IN ('car', 'busses')
AND "vehicle"."category_id" = '1E4FD2C5-C32E-4E3F-91B3-45478BCF0185'
  

В моей базе данных есть только одно транспортное средство. Он имеет два тега -> car и busses (это тестовые данные).
Поэтому, когда я запускаю запрос, он возвращает точно такое же транспортное средство с указанием 2 тегов, которые у него есть.

введите описание изображения здесь

Как мне заставить его вернуть транспортное средство один раз? Я действительно не хочу возвращать tag_name . Я только хочу отфильтровать и вернуть все транспортные средства, у которых есть оба тега car и busses . Если одно транспортное средство имеет оба этих тега, оно должно возвращать только это транспортное средство. Но вместо этого он дважды возвращает одно и то же транспортное средство, показывая его теги.

Ответ №1:

Это должно сработать для вас.

 SELECT i.*
FROM "interest" as "i"
where i.id in (
    select it.interest_id
    from interest_tag_pivot it
    join tag t on it.tag_id = t.id
    where t.name in ('car', 'busses')
    group by it.interest_id
    having count (*) = 2
)
and i.category_id = '1E4FD2C5-C32E-4E3F-91B3-45478BCF0185'
  

Ответ №2:

Не JOIN — объединения приводят к дублированию. Поместите логику всех тегов в WHERE EXISTS(...) или аналогичную.

Здесь сравниваются два скалярных подзапроса WHERE , попробуйте это (важно! — предполагается, что теги для каждого транспортного средства не могут дублироваться, поэтому мы можем сравнить их количество):

 WITH required_tags(val) AS (
  VALUES ('car'),
         ('busses')
)
SELECT "vehicle"."id",
       "vehicle"."description",
       "tag"."id" AS "tag_id", 
       "tag"."name" AS "tag_name"
FROM "vehicle" 
WHERE "vehicle"."category_id" = '1E4FD2C5-C32E-4E3F-91B3-45478BCF0185'
  AND (
    -- count matching tags...
    SELECT count(1)
    FROM "vehicle_tag_pivot"
      INNER JOIN "tag" ON "vehicle_tag_pivot"."tag_id" = "tag"."id"
    WHERE "vehicle"."id" = "vehicle_tag_pivot"."vehicle_id"
      AND "tag"."name" IN (SELECT val FROM required_tags)
    ) = (
      -- ...equals to count required tags
      SELECT count(1) 
      FROM required_tags 
    )