2012-07-04 74 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

谢谢,这是工作,但我认为它会比我已经有的,因为你搜索整个分贝,而不是搜索子查询。 –