2010-04-06 48 views
0

我正在用標記過濾功能爲自己構建一個筆記記錄應用程序,但在嘗試使用標記抓取筆記時遇到問題。標記過濾器需要使用AND而不是IN,因爲它有助於更​​好地縮小我所尋找的範圍。有三個WHERE語句的MySQL LEFT JOIN問題

我的表可以這樣來配置:

+ notes   note_id | note_title | note_uid 

+ tags   tag_id | tag_title 

+ notes_tags  nt_id | nt_note_id | nt_tag_id 

的notes_tags表跟蹤的所有註釋標籤。

我不擔心有關標籤任何信息的返回,所以這裏是LEFT JOIN我使用目前只得到筆記與只有1個標籤的例子。

SELECT * FROM notes_tags LEFT JOIN注意事項note_id = nt_note_id WHERE note_uid IN(1)和nt_tag_id = 10

這個查詢運行完美,它抓住所有的音符與單個標籤 。然而,我在使用這樣的查詢問題 「見真章」 我的筆記:

SELECT * FROM notes_tags LEFT JOIN注意事項note_id = nt_note_id WHERE note_uid IN(1)和nt_tag_id = 10 和nt_tag_id = 11

我在做什麼錯誤的語法?

+0

您試圖獲取標籤10和11中的註釋,我接受它?你不能只用一個AND來做,看看昨天這個類似的問題:http://stackoverflow.com/questions/2581067/mysql-experts-need-help-with-intersect/2581145#2581145 – 2010-04-06 21:09:14

回答

2

假設你想要識別帶有nt_tag_ids 10和nt_tag_id爲11的相關notes_tags記錄的註釋,那麼外連接只是使DBMS比需要的更努力工作。

這似乎是最明顯的解決方案:

SELECT * FROM notes n 
WHERE EXISTS (SELECT 1 FROM notes_tags nt 
    WHERE n.note_id=nt.nt_note_id 
    AND nt.nt_tag_id=10) 
AND EXISTS (SELECT 1 FROM notes_tags nt2 
    WHERE n.note_id=nt2.nt_note_id 
    AND nt2.nt_tag_id=11); 

另一種方法是:

SELECT n.*, COUNT(*) 
FROM notes n, 
notes_tags nt 
WHERE n.note_id-nt.nt_note_id 
AND nt.nt_tag_id IN (10,11) 
GROUP BY .... /* need to add these */ 
HAVING COUNT(*)=2; 

注意這個前提是他們是nt_note_id和nt_tag_id在notes_tags表的唯一約束。

但上述兩者只會返回筆記表中的數據。如果你需要提取MN分解表中相應的行:

SELECT * 
FROM notes n, 
notes_tags nt, 
notes_tags nt2 
WHERE n.note_id=nt.nt_note_id 
AND n.note_id=nt2.note_id 
AND nt.nt_note_id=nt2.nt_note_id /* can help the optimizer come up with a faster query */ 
AND nt.nt_tag_id=10 
AND nt2.nt_tag_id=11 

您可能要添加別名的輸出列作解析響應更容易一點。而不是在where子句中像這樣使用「或」

+0

謝謝!這工作完美。 – hatfieldajoshua 2010-04-08 14:10:33

2

nt_tag_id = 10 AND nt_tag_id = 11這將始終返回false

使用nt_tag_id in (10,11)代替

如果你需要這兩個標籤的存在與加入標籤見下表回答兩次

+0

使用如果他想要10 *或* 11的筆記,IN(10,11)將會奏效,但如果他想要10 *和* 11的筆記,則取決於他所瞄準的筆記。 – 2010-04-06 21:09:51

+0

我希望我是對的猜測,一個領域不能等於10和11同時 – vittore 2010-04-06 21:12:00

2

這將只返回有 TAG_ID筆記10和11.

SELECT notes.* 
FROM notes 
INNER JOIN notes_tags a ON notes.note_id = a.nt_note_id 
         AND a.nt_tag_id = 10 
INNER JOIN notes_tags b ON notes.note_id = b.nt_note_id 
         AND b.nt_tag_id = 11 
0

您正在使用「AND」:

SELECT * FROM notes_tags LEFT JOIN notes ON note_id = nt_note_id WHERE note_uid IN (1) AND (nt_tag_id = 10 OR nt_tag_id = 11) 

您還可以使用在這樣,如果你要添加更多的nt_tag_id。

SELECT * FROM notes_tags LEFT JOIN notes ON note_id = nt_note_id WHERE note_uid IN (1) AND nt_tag_id IN (10, 11)