我正在为我的网站创建一个简单的过滤系统。场地和便利设施之间存在许多关系。这是我的桌子。
注意:所有ID均为uuid。使它们简明扼要
场地:
| id | name | _________________________ | 'aaa' | 'first venue' | | 'bbb' | 'second venue' | | 'ccc' | 'third venue' |
便利设施:
| id | name | ___________________________ | 'aaa' | 'first amenity' | | 'bbb' | 'second amenity' | | 'ccc' | 'third amenity' |
| amenity_id | venue_id | ______________________________ | 'aaa' | 'aaa' | | 'bbb' | 'aaa' | | 'ccc' | 'aaa' | | 'aaa' | 'bbb' | | 'bbb' | 'ccc' |
我正在尝试编写查询以返回至少具有所有已通过amenity_ids传递的场所。例如,传入amenity_idsaaa和bbb。
aaa
bbb
输出我正在寻找何时传入的设施ID是aaa和bbb。
| id | name | _________________________ | 'aaa' | 'first venue' |
最初我尝试了这个查询
select * from venues INNER JOIN amenity_venue ON amenity_venue.venue_id = venues.id where amenity_id in ('aaa', 'bbb');
这将返回所有具有amenity_idaaa或bbb
所以我天真地尝试了
select * from venues INNER JOIN amenity_venue ON amenity_venue.venue_id = venues.id where amenity_id = 'aaa' and amenity_id = 'bbb';
这什么也没返回。我正在尝试编写一个查询,其中返回amenity_idsaaa和bbb仅在场所传递的查询,aaa因为它是唯一与这两种便利设施都有关系的场所。而且,便利设施的数量在查询之间是动态的。
您可以通过将ID汇总到一个数组中,然后将其与预期ID列表进行比较来做到这一点:
select v.* from venues v join amenity_venue av ON av.venue_id = v.id group by v.id having array_agg(av.amenity_id) @> array['aaa', 'bbb'];
上面的示例假定已将venue.id其声明为主键(因为group by)。
venue.id
group by
如果您只想传递便利设施名称,则实际上并不需要对查询中的ID进行硬编码:
select v.* from venues v join amenity_venue av ON av.venue_id = v.id group by v.id having array_agg(av.amenity_id) @> array(select id from amenities where name in ('first amenity', 'second amenity'));
在线示例:https://rextester.com/FNNVXO34389