1

我有两个表(注释和标签)。标签具有注释的外键。单个笔记记录可能有多个标签记录。

我试图只选择包含所有所需标签的注释。

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 子句的帮助。没有子选择可以做到这一点吗?

4

3 回答 3

2

假设 tags(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
于 2009-11-19T18:46:39.920 回答
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'在我的示例中)。

于 2009-11-19T18:36:00.333 回答
0

如果还不算太晚,那么拥有一个 NoteTag 表不是更好吗 - 这样您将拥有笔记、标签、notetag 表,并且您可以使用简单的查询和 AND 运算符来查找您想要的内容?)

于 2009-11-19T18:35:31.253 回答