我有两张桌子(笔记和标签)。标签有备注的外键。单个音符记录可能有多个标签记录。
我正在尝试仅选择包含所有所需标签的音符。
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子句。没有子选择可以做到这一点吗?
答案 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运算符来找到你想要的东西吗?)