从table1中选择WHERE table2包含所有搜索参数

时间:2009-11-19 18:32:32

标签: mysql where-clause

我有两张桌子(笔记和标签)。标签有备注的外键。单个音符记录可能有多个标签记录。

我正在尝试仅选择包含所有所需标签的音符。

SELECT notes.*, tags.* FROM notes LEFT JOIN tags ON notes.id = tags.note_id 
WHERE {my note contains all three tags I would like to search on}

使用WHERE tag.name IN('fruit','meat','vegetable')将带回所有带有“fruit”,“meat”或“vegetable”标签的音符。我只想要留下有三个“水果”,“肉”和“蔬菜”标签的笔记。

我可以带回多条记录(上面的查询会产生每个标记的记录)。

我需要帮助我的where子句。没有子选择可以做到这一点吗?

3 个答案:

答案 0 :(得分:2)

假设标签(note_id,tag)被声明为UNIQUE或PK,那么您可以使用:

SELECT note_id, COUNT(tag) FROM tags
WHERE tag IN ('fruit', 'vegetable', 'meat')
GROUP BY note_id
HAVING COUNT(tag) >= 3

根据OP的评论进一步回答如下。获取匹配的记录的所有标记:

SELECT * FROM tags
INNER JOIN
(
SELECT note_id, COUNT(tag) FROM tags
WHERE tag IN ('fruit', 'vegetable', 'meat')
GROUP BY note_id
HAVING COUNT(tag) >= 3
) search_results
ON search_results.note_id = tags.note_id

答案 1 :(得分:1)

根据请求没有子选择:

SELECT  notes.*
FROM    notes
JOIN    tags
ON      tag.note = notes.id
        AND tag.name IN ('fruit','meat','vegetable')
GROUP BY
        notes.id
HAVING  COUNT(*) = 3

更有效的方法是:

SELECT  notes.*
FROM    (
        SELECT  to.note
        FROM    tags to
        WHERE   to.name = 'meat'
        AND     EXISTS
                (
                SELECT  NULL
                FROM    tags ti
                WHERE   ti.note = to.note
                        AND to.name IN ('fruit', 'vegetable')
                LIMIT 1, 1
                )
        ) t
JOIN    notes
ON      note.id = t.note

这里的诀窍是首先将搜索放在最具选择性的标签(我的例子中为'meat')上。

答案 2 :(得分:0)

如果还不算太晚,那么拥有一个NoteTag表会不会更好 - 所以你会有注释,标签,notetag表,你可以使用简单的查询和AND运算符来找到你想要的东西吗?)