2010-09-21 75 views
1

我正在嘗試爲表(公寓)創建過濾器,並通過apartsments_features表與apartment features建立多對多關係。在子查詢中的MySQL交集

我想只包括全部的某些功能(在窗體上標記爲「是」)的公寓,但不包括具有任何其他功能(標記爲「否」)的公寓。我意識到太遲了,我不能在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 

我敢肯定有辦法做到這一點,但此刻我的知識僅限於較簡單的左更小,右連接。

+0

是的,這是一個錯字。 – Zahymaka 2010-09-21 21:47:50

回答

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 
+0

謝謝。我需要將WHERE移動到您的查詢中,但是如果mysql之後發生錯誤,則會發生錯誤。非常感謝你! – Zahymaka 2010-09-22 17:21:18

+0

D'oh!我應該已經發現了!查詢相應修改 - 謝謝。 – 2010-09-22 17:38:55

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 

加入此查詢到公寓表的結果,以獲得名稱等

+0

這是如何工作的,如果我只是排除。由於這是一個很長的「是」和「否」的列表,我可以在任何時候排除一些結果,或者只包括一些例如如果我只有Yeses或Nos。 – Zahymaka 2010-09-21 21:47:17

+0

@ Zahymaka:如果你只是排除了查詢可以做得簡單很多。 – 2010-09-21 22:01:24

+0

非常感謝。班尼斯特的代碼在我需要的時候能夠更好地工作,因爲我需要去處理其他的事情。儘管如此,我的確讓你的答案滿意。我學到了一些東西,在這個項目的某個階段應該派上用場。 – Zahymaka 2010-09-22 17:20:05