A variation on Gordon's answer:
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
The essential differences:
Works for any number of amenity ids you put in YOUR LIST HERE
Returns an output in the format you requested
How it works:
You want to know all the venues that have every one of the amenities listed
We reduce the table amenity_venue to just a list of all the amenities we are interested in (in your case, 1 and 2). Now we want to know which venues have every single different amenity
We do this by counting the number of amenities a venue has and demanding it be equal to the number of distinct amenities in the list. This is the purpose of the group by/having- it counts the distinct amenities per venue and compares it to the distinct count of amenities in the whole list.
The CTE contains a LEFT JOIN that produces a list of amenity id and venues that have that ID, but critically it also produces an amenity ID paired with NULL if no venues have that amenity. If we thus demanded that a venue have amenities 1,2,3 then it means that the distinct list of amenities in the CTE is three and this query: ((select count(distinct amenity_id) from cte)
) produces a count of 3. However, remember that no venue has amenity 3, so the most amenable venue (1) has amenities 1 and 2, the GROUP BY/HAVING groups up on venue ID, and produces a count of 2 amenities. Because 3 <> 2, it means our demand of "venues that have 1,2,3 amenities" produces no results. If we didn't have this left join, and purely relied on the amenities assigned to venues, then asking for 1,2,3, would produce a list of venues that have just amenities 1 and 2, and this pair would be distinct counted to be 2 (should be 3) and the query would deliver wrong results
After a list of venue ids is derived from this process the venue id is joined back to amenity_venue to retrieve the requested output