2013-02-12 52 views
1

首先,請注意,我沒有什麼經驗與SQL(在這種情況下,sqlite3),所以即使這個問題的標題可能是ill-措詞。sql JOIN與布爾值WHERE

假設我有筆記(n)的表,和關鍵字的那些音符(k)的表,最後一表的一個或多個關鍵詞關聯到每個音符(nk)。我想要做的是找到每個包含兩個(或更多)關鍵字的註釋。

爲了更具體一些,下面(sqlite3)是我如何設置數據庫。

CREATE TABLE n(nid integer primary key autoincrement, content); 
CREATE TABLE k(kid integer primary key autoincrement, content); 
CREATE TABLE nk(nkid integer primary key autoincrement, nid, kid); 
INSERT INTO n(content) VALUES ("note 1"); 
INSERT INTO n(content) VALUES ("note 2"); 
INSERT INTO k(content) VALUES ("keyword 1"); 
INSERT INTO k(content) VALUES ("keyword 2"); 
INSERT INTO nk(nid, kid) VALUES (1, 1); 
INSERT INTO nk(nid, kid) VALUES (1, 2); 
INSERT INTO nk(nid, kid) VALUES (2, 1); 

有了這個,我可以得到筆記標記爲1的關鍵字ID與

select * from n LEFT JOIN nk ON nk.nid = n.nid WHERE nk.kid=1; 

,我的問題是,我怎樣才能得到注意到關鍵字ID 1 2.我已經在網絡上做了一些搜索,但我擔心我的知識不足以考慮良好的搜索條件。我希望這個網站上的某個人能夠提供幫助,並且 - 重要的是 - 如果這是一個愚蠢的問題,我很抱歉。

回答

1

爲了提高@ GordonLinoff的回答是:

select * from n where nid IN 
(select nid 
    from (select * from nk where kid in (1,2)) s 
    group by nid 
    having count(distinct s.kid) = 2) 

這將讓那些有kid匹配1和2的記錄,即使其他kid值可能存在(3,4等)。 sqlfiddle here

+0

這看起來很完美。非常感謝! – dank 2013-02-12 19:31:20

1

如果你只是想有兩個以上關鍵字的筆記,使用聚合:

select nid 
from nk 
group by nid 
having count(*) >= 2 

如果關鍵字可以在列表中,使用複製:

having count(distinct nk.kid) >= 2 

要獲得關鍵字筆記1和2,使用:

having max(case when kid = 1 then 1 else 0 end) = 1 and 
     max(case when kid = 2 then 1 else 0 end) = 1 

having子句在這種情況下只是創建一個標誌,只要它看到其中一個值。邏輯然後確定在給定票據的一組關鍵字中是否已經看到該值。

0

select * from n LEFT JOIN nk ON nk.nid = n.nid WHERE nk.kid in (1,2)

+2

OP要求值1和2的孩子都與nid相關聯。如果1或2關聯,此查詢將返回記錄。 – PinnyM 2013-02-12 16:07:34