SQL select查询内部连接多对多的重构

时间:2012-07-04 21:48:33

标签: sql

我在条目和关键字之间存在多对多关系,并带有连接表entries_keywords。我想获取键'wake'和'up'的所有条目。我想出的唯一方法就是这个。如果我想引入另一个搜索词,它会变得更糟。你怎么重构这个?是否有另一种方法来加入它而不是使用子查询?

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';

2 个答案:

答案 0 :(得分: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是您要检查的列表中的关键字数量。

答案 1 :(得分: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'
;

这将返回“wake”的所有条目+“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'
;

这将返回包含两个关键字的所有条目。