这个问题与以下内容完全相同:
我有下表
amenity_venue (ids are uuids, made them ints for simplicty)
--------------------------
| amenity_id | venue_id |
--------------------------
| 1 | 1 |
| 2 | 1 |
| 1 | 2 |
| 1 | 3 |
我正在尝试编写一个查询,我选择amenity_id
,但只返回结果,如果venue_id
同时有amenity_ids
。
我知道这是破碎的,但是:
select *
from amenity_venue where amenity_id in (1, 2)
having amenity_venue.venue_id = amenity_venue.venue_id
我的查询应该只返回
--------------------------
| amenity_id | venue_id |
--------------------------
| 1 | 1 |
| 2 | 1 |
因为场地1是唯一同时具有amenity_id
1和2的场地。我怎么能写这样的查询?
您可以使用聚合来获取
select venue_id
from amenity_venue
where amenity_id in (1, 2)
group by venue_id
having count(distinct amenity_id) = 2; -- this is the number of values in the `in` list
如果表中没有重复项,您可以使用count(*)
。
如果你想要原始行(而不仅仅是场地),那么我会建议exists
:
select av.*
from amenity_venue av
where (av.amenity_id = 1 and
exists (select 1 from amenity_venue av2 where av2.venue_id = av.venue_id and av2.amenity_id = 2)
) or
(av.amenity_id = 2 and
exists (select 1 from amenity_venue av2 where av2.venue_id = av.venue_id and av2.amenity_id = 1)
);
在添加新的amenity_id的情况下,以下查询是可缩放的。
SELECT *
FROM amenity_venue
WHERE venue_id IN
(
--Get venue_id where all amenity_id exist
SELECT venue_id
FROM amenity_venue
GROUP BY venue_id
HAVING count(*) =
(
-- Get number of unique amenity_id
SELECT count(DISTINCT amenity_id) FROM amenity_venue
)
)
戈登答案的一个变种:
WITH cte AS
(
select a.id as amenity_id, av.venue_id
from amenity a LEFT JOIN amenity_venue av ON a.id = av.amenity_id
where a.id in (1,2)
)
SELECT av.*
FROM
amenity_venue av
INNER JOIN
(
SELECT venue_id
FROM cte
GROUP BY venue_id
HAVING count(distinct amenity_id) =
(select count(distinct amenity_id) from cte)
) x
ON av.venue_id = x.venue_id
本质区别:
适用于您在此处列出的任何数量的设施ID
以您请求的格式返回输出
您想知道列出所有设施的所有场地
我们将表amenity_venue缩减为我们感兴趣的所有便利设施列表(在您的情况下,1和2)。现在我们想知道哪些场馆有不同的舒适度
我们通过计算场地的设施数量并要求它等于列表中不同设施的数量来实现这一点。这是团体的目的/由 - 它计算每个场地的不同设施,并将其与整个列表中的独特设施数量进行比较。
CTE包含一个LEFT JOIN,它生成一个具有该ID的便利设施ID和场所列表,但是如果没有场地具有该设施,它也会产生一个与NULL配对的设施ID。如果我们因此要求场地有1,2,3号设施,那么这意味着CTE中不同的设施清单是三个,这个查询:((select count(distinct amenity_id) from cte)
)产生的数量为3.但是,请记住没有场地有3个设施。 ,所以最适合的场地(1)有设施1和2,GROUP BY / HAVING组合了场地ID,并产生2个设施。因为3 <> 2,这意味着我们对“拥有1,2,3个设施的场所”的需求不会产生任何结果。如果我们没有这个离开加入,并且纯粹依赖于分配给场地的设施,那么要求1,2,3,将产生一个只有设施1和2的场地列表,并且这对将是不同的计数为2(应为3),查询将产生错误的结果
在从该过程导出场地ID列表之后,场地ID被连接回amenity_venue以检索所请求的输出