1

2 つのテーブル (メモとタグ) があります。タグにはメモへの外部キーがあります。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" タグを持つすべてのメモが返されます。「果物」、「肉」、「野菜」の 3 つのタグがすべて含まれているノートのみを返したいと考えています。

複数のレコードを取得しても問題ありません (上記のクエリでは、各タグのレコードが生成されます)。

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 に答える