子查询中的MySQL交集

时间:2010-09-21 21:35:15

标签: sql mysql

我正在尝试为(公寓)列表创建一个过滤器,通过apartment features表与apartsments_features建立多对多关系。

我希望仅包含所有某些功能的公寓(在表单上标记为“是”),不包括具有任何其他设置功能(标记为“否”)的所有功能。我意识到太晚了,我无法在MySQL中使用INTERSECTMINUS

我的查询类似于:

SELECT `apartments`.* FROM `apartments` WHERE `apartments`.`id` IN (
    SELECT `apartments`.`id` FROM `apartments` INTERSECT (
        SELECT `apartment_id` FROM `apartments_features` WHERE `feature_id` = 103 
INTERSECT SELECT `apartment_id` FROM `apartments_features` WHERE `feature_id` = 106
    ) MINUS (
    SELECT `apartment_id` FROM `apartments_features` WHERE `feature_id` = 105 UNION 
    SELECT `apartment_id` FROM `apartments_features` WHERE `feature_id` = 107)
)
ORDER BY `apartments`.`name` ASC

我很确定有办法做到这一点,但目前我的知识仅限于简单的左右连接。

2 个答案:

答案 0 :(得分:2)

您可以尝试这样的事情:

SELECT apartment_id
FROM
(
    SELECT apartment_id
    FROM apartments_features
    WHERE feature_id IN (103, 106)
    GROUP BY apartment_id
    HAVING COUNT(*) = 2
) T1
LEFT JOIN
(
    SELECT apartment_id
    FROM apartments_features
    WHERE feature_id IN (105, 107)
) T2
ON T1.apartment_id = T2.apartment_id
WHERE T2.apartment_id IS NULL

将此查询的结果加入到apartments表中以获取名称等

答案 1 :(得分:2)

采用略有不同的方式:

select a.*
from apartments a
join apartments_features f1 
on a.apartment_id = f1.apartment_id and f1.feature_id in (103,106) -- applicable features
where not exists
(select null from apartments_features f2
 where a.apartment_id = f2.apartment_id and f2.feature_id in (105,107) ) -- excluded features
group by f1.apartment_id
having count(*) = 2 -- number of applicable features