Да, вы захотите использовать (другое) соединение. Я думаю, что следующее должно сделать это:
SELECT lst.`id`, lst.<column>, ...
FROM `listings` lst, `map` m, `map` m2
WHERE m.`category_id` = 18 AND m2.`category_id` = 20
AND m.`listing_id` = lst.`id`
AND m2.`listing_id` = lst.`id`
Другая версия, вдохновленная предложениями Джерма, но эта работает (обратите внимание, я заменил id
на category_id
для ясности):
select l.listing_id
from listings l
join (select m.listing_id, count(*) as cnt from map m where
m.category_id in (18,20)
group by m.listing_id) cat_matches
on cat_matches.listing_id = l.listing_id
where cat_matches.cnt = 2; -- 2 is the number of distinct categories to match
Гадкий, а? И отбор может быть не настолько эффективным ... но:
select l.listing_id
from listings l
join map m on l.listing_id=m.listing_id
where m.category_id in (18,20)
group by l.listing_id
having COUNT(*)=2;
Вы можете исключить этот подвыбор, получив все необходимые вам строки и затем отфильтровав их. Обратите внимание, что это решение предполагает, что линии в таблице карты являются уникальными (что должно быть так, поскольку PK должен быть определен как listing_id
, так и category_id
).