2012-07-04 102 views
4

我在連接表entries_keywords中有條目和關鍵字之間的多對多關係。我想要獲取'wake'和'up'兩個鍵的所有條目。我想出的唯一方法就是這樣。如果我想扔另一個搜索詞,它會變得更糟。你如何重構這個?有沒有其他的方式來加入它比使用子查詢?SQL選擇查詢內部連接多對多重構

select * 
from 
(
    select * 
    from entries e 
    inner join entries_keywords ek 
     on e.id = ek.entry_id 
    inner join keywords k 
     on ek.keyword_id = k.id 
    where k.key = 'wake' 
) e 
inner join entries_keywords ek 
    on e.id = ek.entry_id 
inner join keywords k 
    on ek.keyword_id = k.id 
where k.key = 'up'; 
+0

是否要檢索具有***'wake'和'up'或者只是其中一個***的記錄? –

+0

您使用SQL Server嗎? MySQL的? – rcdmk

+0

我正在使用Sqlite3 –

回答

4

如果你只是想檢索具有關鍵字中的至少一個項目,你可以這樣做:

SELECT 
    a.* 
FROM 
    entries a 
INNER JOIN 
    entries_keywords b ON a.id = b.entry_id 
INNER JOIN 
    keywords c ON b.keyword_id = c.id 
WHERE 
    c.key IN ('wake', 'up') 

如果你想檢索具有所有關鍵字列表中的條目,添加GROUP BYHAVING

SELECT 
    a.* 
FROM 
    entries a 
INNER JOIN 
    entries_keywords b ON a.id = b.entry_id 
INNER JOIN 
    keywords c ON b.keyword_id = c.id 
WHERE 
    c.key IN ('wake', 'up') 
GROUP BY 
    a.id 
HAVING 
    COUNT(*) = 2 

2是你正在檢查的列表中的關鍵字數量。

+0

謝謝,但使用最後一個有,我得到的結果只匹配除了匹配兩個單詞之外的其中一個單詞。只有匹配關鍵字_both_的條目必須包含在結果中。 –

+0

@OpptattJobber,這很奇怪,不應該發生。我的猜測是你的數據有某種重複。多對多表在*'entry_id'和'keyword_id'列的組合中是唯一的嗎?此外,在「關鍵字」表格中,是否有可能出現多次但使用不同ID的關鍵字? –

+0

我發佈在頂部的查詢完全是這樣的,但它很醜,可能比沒有子查詢的抓取慢。您對相同數據的查詢會返回更多條目。每個關鍵字一個ID,每個條目都是唯一的。 –

0

如果我得到你需要的權利,你可以使用一個UNION加入列表中的2個查詢結果:

SELECT * 
FROM entries e 
INNER JOIN entries_keyworkds ek 
    ON e.id = ek.entry_id 
INNER JOIN keywords k 
    ON ek.keywork_id = k.id 
WHERE k.key = 'WAKE' 

UNION 

SELECT * 
FROM entries e 
INNER JOIN entries_keyworkds ek 
    ON e.id = ek.entry_id 
INNER JOIN keywords k 
    ON ek.keywork_id = k.id 
WHERE k.key = 'up' 
; 

這將返回所有條目爲「喚醒」 +所有的「條目向上」。

要查找條目與這兩個鍵,使用INTERSECT

SELECT * 
FROM entries e 
INNER JOIN entries_keyworkds ek 
    ON e.id = ek.entry_id 
INNER JOIN keywords k 
    ON ek.keywork_id = k.id 
WHERE k.key = 'WAKE' 

INTERSECT 

SELECT * 
FROM entries e 
INNER JOIN entries_keyworkds ek 
    ON e.id = ek.entry_id 
INNER JOIN keywords k 
    ON ek.keywork_id = k.id 
WHERE k.key = 'up' 
; 

這將返回有兩個關鍵字的所有條目。

+0

如果一個條目同時具有'wake'和'up'這兩個關鍵字,那麼由於'UNION ALL'的原因,結果集中會有重複條目。只需使用'UNION'來刪除重複項。 –

+0

謝謝。你是對的。我會編輯我的答案。想想我只是累了(一些糟糕的睡眠之夜)。 – rcdmk

+0

謝謝,這是工作,但我認爲它會比我已經有的,因爲你搜索整個分貝,而不是搜索子查詢。 –