2010-03-04 102 views
0

有沒有更好的方式來使這個查詢工作?如果有可用的解決方案,我正在尋找更高效的解決方案。可以對此MySQL查詢(使用子查詢)進行優化嗎?

SELECT `unitid`, `name` FROM apartmentunits WHERE aptid IN (
    SELECT `aptid` FROM rentconditionsmap WHERE rentcondid = 4 AND condnum = 1 
) AND aptid IN (
    SELECT `aptid` FROM rentconditionsmap WHERE rentcondid = 2 AND condnum = 1 
) ORDER BY name ASC 

回答

3

我想你想在這裏自我加入。加入表rentconditionsmap自己,並指出加入任何一方的條件。然後將該查詢的結果加入apartmentunits

(注:沒有測試過這一點,可能需要一些調整...)

SELECT `unitid`, `name` FROM `apartmentunits` 
WHERE `unitid` IN (
     SELECT `unitid` FROM `rentconditionsmap` r1, `rentconditionsmap` r2 
     WHERE r1.`unitid` = r2.`unitid` 
      AND r1.`rentcondid` = 4 
      AND r1.`condnum` = 1 
      AND r2.`rentcondid` = 2 
      AND r2.`condnum` = 1) 
ORDER BY `name` ASC 
+0

@tenner:您的查詢工作。現在,如果我需要添加更多的setscondcondid和condnum,我只想在該查詢中繼續進行更多連接嗎? SELECT unitid,name FROM apartmentunits WHERE aptid IN(SELECT r1.aptid FROM rentconditionsmap r1 JOIN rentconditionsmap r2 ON r1.aptid = r2.aptid WHERE r1.rentcondid = 4 AND r1.condnum = 1 AND r2.rentcondid = 2 AND r2 .condnum = 1) – 2010-03-04 19:54:55

+0

是的,如果您有三個條件,那麼在自聯接中需要三個表。 – Tenner 2010-03-04 20:07:31

0

是,使用連接。大多數數據庫管理系統都會優化連接,使其不需要拉出不需要的行。 MySQL仍然使用嵌套循環,但我相信Oracle會使用散列連接。

所以這個查詢可能會更好地被表達爲

Select `unitid`, `name` FROM apartmentunits au 
INNER JOIN rentconditionsmap rcm1 
USING (aptid) 
INNER JOIN rentconditionsmap rcm2 
USING (aptid) 
WHERE rcm1.rentcondid = 4 
AND rcm1.condnum = 1 
AND rcm2.rendcondid = 2 
AND rcm2.condnum = 1 
+0

更簡單地說,不管DBMS如何,連接順序都會被優化,並且可能會更好地基於來自apartmentunits表的FETCH的統計信息,並使用其數據來選擇租用條件圖上的數據。在你的查詢中,你基本上決定了連接順序。 – 2010-03-04 19:32:42

1
SELECT a.`unitid`, 
     a.`name` 
FROM apartmentunits a 
     INNER JOIN rentconditionsmap r 
     ON a.aptid = r.aptid 
    AND 
     r.rentcondid in (2,4) 
    AND 
     r.condnum = 1 
ORDER BY a.`name`