2012-03-21 5 views
0

アイテムの1つ、それらのアイテムのタグの1つ、タグIDとタグ名のマッピングの3つのテーブルを考えてみましょう。アイテムとタグのMysql JOIN

アイテム:

ITEM ID ITEM NAME 
------------------- 
1   Item 1 
2   Item 2 
3   Item 3 

タグ:

ID TAG ID ITEM ID 
1  1  1 
2  2  1 
3  3  1 
4  1  2 
5  1  3 

タグ名:

TAG ID TAG NAME 
1  TAG_A 
2  TAG B 
3  TAG C 

だから、唯一の項目1は、タグTAG_A、TAG_BとTAG_Cを持っています。

3つのINNER JOINを実行せずにTAG_A、TAG_B、およびTAG_Cを持つすべてのアイテムを取得するselectはどのようにして行いますか?言い換えれば、私は私が選択を行うと、

INNER JOIN item_tags pt4 ON pt4.item_id = p.item_id AND pt4.tag_id = 1 
INNER JOIN item_tags pt13 ON pt13.item_id = p.item_id AND pt13.tag_id = 2 
INNER JOIN item_tags pt19 ON pt19.item_id = p.item_id AND pt19.tag_id = 3 

を言うことができます知っているが、それは右、非効率的であることを持っていますか?

項目WHERE FROM

SELECT *のようなサブクエリ、およそどのような...とInをITEM_ID(

これを((1、2、3)TAG_ID item_tags FROMのitem_id を選択)

+2

あなたが機能しなかったことは何をしようとしたのですか? –

+1

すべてのタグを持つ、または指定したタグを持つアイテムを返すクエリを探していますか? – iWantSimpleLife

+0

@iWantSimpleLifeは、指定された3つのタグTAG_A、TAG_B、およびTAG_Cだけを使用します。 –

答えて

2

この文字列で検索してください -

SELECT t.item_id FROM tags t 
    JOIN tag_names tn 
    ON t.tag_id = tn.tag_id 
GROUP BY 
    t.item_id 
HAVING 
    COUNT(DISTINCT t.tag_id) = (SELECT COUNT(*) FROM tag_names) 
+0

私はidマッピングを行うための名前を持っているので、サブクエリとして持っているものを使っただけです - SELECT t.item_id FROMタグt GROUP BY t.item_idカウント(DISTTTTAG_ID)= <タグ数>。 GROUP BYとCOUNTは私が探していたものでした。 –

0

最初のクエリ(エイリアス化されたsqlvars)は、タグ名にいくつのタグがあるかという単一の@NumTags変数を作成しますそれで、すべての適格なタググループでそれを行う必要はありません。

2番目のクエリ(別名HasAllTags)は、項目数が@NumTagsの合計数と等しいitemidでグループ化された項目を取得します。

最後に、HasAllTagsはアイテムに結合されてデータを取得します。

select 
     I.* 
    from 
     (select @NumTags := (select count(*) from TagName)) sqlvars, 
     (select t.ItemID 
      from Tags t 
      group by t.ItemID 
      having count(*) = @NumTags) HasAllTags 
     JOIN Items I 
      on HasAllTags.ItemID = I.ItemID