2011-06-13 68 views
1

我有3個MySQL表沒有關聯:標籤,place_tags,event_tags如何找出是否與其他表

標籤:

--------------------- 
| tag_id | name | 
--------------------- 
| 1  | cat | 
--------------------- 
| 2  | dog | 
--------------------- 
| 3  | fish | 
--------------------- 

place_tags:

------------------------- 
| place_id | tag_id | 
------------------------- 
|  1  |  1 | 
------------------------- 
|  2  |  2 | 
------------------------- 
|  3  |  1 | 
------------------------- 

event_tags:

------------------------- 
| event_id | tag_id | 
------------------------- 
|  1  |  1 | 
------------------------- 
|  2  |  2 | 
------------------------- 
|  3  |  1 | 
------------------------- 

我想寫一個闕ry將查看tags表中的所有標籤,並將查找其中哪些與其他表中的任何一個沒有關聯。在這個例子中,你可以看到tag_id 3沒有用在任何其他表中,所以我想選擇它並輸出它。

+0

請停止在標題中寫入標籤。 – 2011-06-13 00:28:36

回答

1
select * from tag 
where not exists (select * from place_tags where tag_id = tag.tag_id) 
and not exists (select * from event_tags where tag_id = tag.tag_id) 

或更有效的,但也許更難閱讀:

select * from tag 
where tag_id not in (
    select tag_id from place_tags where tag_id is not null 
    union 
    select tag_id from event_tags where tag_id is not null) 

注:where tag_id is not null需要,因爲如果其中一列有null一個tag_id,該in永遠是false

+0

第二個查詢比第一個查詢少*效率高,因爲它從*兩個表*中選擇*每一行*,並且在標記表中每行*時都會這樣做。如果你有幾行以上的東西,速度會非常慢。 – rid 2011-06-13 13:17:15

+0

@Radu不幸的是,你錯了相對效率:第一個查詢將對標記**中的EVERY ROW(它們被稱爲「相關子查詢」)的place_tags和event_tags進行**查詢 - 儘管它們可能是索引查詢。第二個選項只對place_tags和event_tags進行2次查詢,儘管它們是表掃描(索引不會用於空查找)。 EG,即使標籤中只有100行,兩個表掃描總是會比200個單獨的查詢更快。想象一下,如果有100萬行! – Bohemian 2011-06-15 08:34:02

+0

@波希米亞人,這將是幸運的錯誤,這將意味着OP現在使用正確的事情。但是,我將不得不再次指出[文檔](http://dev.mysql.com/doc/refman/5.1/en/subquery-restrictions.html),特別是它在其中解釋了「 IN子查詢被翻譯爲相關查詢。儘管這兩個例子都非常不理想,但我同意你的看法。 – rid 2011-06-15 12:25:01

2

一個高效,指數使用,單SELECTJOIN基礎的查詢可以是:

SELECT tags.* 
    FROM tags 
LEFT JOIN place_tags ON place_tags.tag_id = tags.tag_id 
LEFT JOIN event_tags ON event_tags.tag_id = tags.tag_id 
    WHERE place_tags.tag_id IS NULL AND 
      event_tags.tag_id IS NULL 

這同你正在尋找到表,只選擇那些沒有對應關係中的任何一種標籤他們。

+0

這個答案有什麼問題? – rid 2011-06-13 00:17:03

+0

它不會工作,因爲你的where子句中有place_tags.tag_id IS NULL - 沒有這樣的行。你不能找到像這樣缺失的連接行。 – Bohemian 2011-06-13 11:10:23

+0

@波希米亞,當然它會工作。請檢查文檔並運行查詢。 – rid 2011-06-13 13:09:13

相關問題