#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
)