1

3 つのテーブルがあり、そのうちの 1 つは他の 2 つの間のマップです。タグのリストを指定して、タグ付け可能なものにタグ付けされている他のすべてのタグを選択したいと思います。私の問題を視覚化してみます。

tags
--------------
1 | 'email'
2 | 'gmail'
3 | 'yahoo'
4 | 'hotmail'
5 | 'school'
6 | 'not used'

taggables
--------------------------
1  | 'test1@gmail.com'
2  | 'test2@yahoo.com'
3  | 'test3@hotmail.com'
4  | 'test4@gmail.com'
5  | 'test5@myschool.edu'

tagged
------
1,  1   /* test1@gmail.com   --> email */
1,  2   /* test1@gmail.com   --> gmail */
2,  1   /* test2@yahoo.com   --> email */
2,  3   /* test2@yahoo.com   --> yahoo */
3,  1   /* test3@hotmail.com --> email */
3,  4   /* test3@hotmail.com --> hotmail */
4,  1   /* test4@gmail.com   --> email */
4,  2   /* test4@gmail.com   --> gmail */
5,  1   /* test5@myschool.edu--> email */
5,  5   /* test5@myschool.edu--> school */

'email', 'gmail'そのため、結果セットのリストは'yahoo', 'hotmail', 'school'. 私はこれにあまりにも多くの時間を費やしたので、助けが必要です。

4

4 に答える 4

1

このアプローチは、必要なタグを持つすべてのアイテムを取得します。次にin、それらのアイテムのすべてのタグを見つけるために使用します。私があなたの質問を正しく理解していれば、これはあなたが求めているものです:

select distinct td.*
from tagged td join
     tags t
     on td.tagid = t.tagid
where td.itemid in (select itemid
                    from tagged td join
                         tags t
                         on td.tagid = t.tagid
                    where t.tagname in ('gmail', 'email')
                   ) and
      t.tagname not in ('gmail', 'email');
于 2013-08-24T13:15:13.843 に答える
0

1 つの方法は、共通テーブルをそれ自体に結合することです。左側の列 (tagIds を使用) を右側の列 (taggableIds を使用) に結合します。

Select distinct t.TagName  
From tags t
    join tagged d On d.tagId = t.TagId
    join tagged d2 On d2.taggAbleId = d.taggAbleId 
where d2.tagId in (1,2)
    and d2.tagid Not in (1,2) 

または、文字列名を使用した述語が必要な場合は、もう1つ結合します

Select distinct t.TagName  
From tags t
    join tagged d On d.tagId = t.TagId
    join tagged d2 On d2.taggAbleId = d.taggAbleId 
    join tags t2 On t2.tagId = d2.TagId
where t2.tagName in ('gmail', 'email')
    and t2.tagtName Not in ('gmail', 'email')
于 2013-08-24T13:35:47.963 に答える