2010-05-22 102 views
1

我有這張桌子。我想選擇已經不存在的項目,所以我可以創建它們。選擇不存在的東西

 
table tags 
+---------+-------+ 
| tagId | name | 
| 1  | C  | 
| 2  | DX | 
| 3  | CG | 

說SQL是這樣的:

 
select name from tags where name in ('C', 'CG', 'RX') 

你回來'C''CG',所以你知道你必須創建'RX'

有沒有辦法讓這樣的MySQL語句返回'RX'而不是'RX'還不存在?

+0

在任何其他表中是否找到像'RX'這樣的項目,還是隻有一些外部項目列表需要檢查? – 2010-05-22 03:14:33

回答

4

讓我們假設你的標籤(「C」,「CG」,「RX」)是在一個叫做tags_match具有相同結構表如上

,那麼你可以這樣做:

select tr.name 
from tags as tl 
    right join tags_match as tr 
    on tl.name = tr.name 
where tl.name is null 

這會發現所有在tags_match不在標籤的項目,所以這會給你想要的結果,但不幸的是你的標籤(「C」 ,'cg','rx')不在表:(

無論我們可以使用子查詢來「假」表

select tr.name 
from tags as tl 
    right join (select 'cg' as name 
       union select 'c' as name 
       union select 'rx' as name) as tr 
    on tl.name = tr.name 
where tl.name is null 

雖然它有點難看,這會工作。如果你有很多你想測試的項目,你可能需要考慮創建一個真正的臨時表。

+0

+1非常好 - 我忘記了使用UNION創建行,並專注於另一個表中的「名稱」。 – 2010-05-22 03:29:17

1

當然!

select name from tags where name not in ('C', 'CG', 'RX') 

唯一的問題是,如果not in列表很長,這個查詢將是緩慢的,因爲它必須要檢查每行的'name'現場每一個元素,以確定它是否不在列表中,而不是in,當它匹配時,它將停止在該點檢查列表並返回該行。


編輯:將上述溶液是錯誤的。我很抱歉。真正的解決方案如下。

這裏是你如何做到這一點的SQL的一行:

select name from (
    select "C" as name 
    union select "CG" 
    union select "RX" 
) as foo 
where name not in (select name from tags); 
+0

這將返回名稱不在列表中的行。該海報似乎想要返回列表中尚未包含在名單中的一組新行。 – 2010-05-22 03:25:50