1

タグ付けシステムの作成を希望するクライアントがいます。、、、の3 つのテーブルがあります。最後のテーブルは、itemsitem_idと tag_id を関連付けるだけです。私が抱えている問題は次のとおりです。tagsitem_tag_assoc

ユーザーがタグ [1, 2, 3] を含め、タグ [4, 5, 6] を除外するように要求した場合、結果は[1, 2, 3] にすべてのタグ (1 つだけでなく) があり、タグがないすべてのアイテムになります。 [4、5、6]。これを達成するためのクエリを作成するにはどうすればよいですか?

タグを含めるための内部結合を把握するのに十分な調査を行いました。

SELECT i.item_id, i.item_title FROM items AS i INNER JOIN tag_item_assoc AS tia1 ON (tia1.item_id = i.item_id AND tia1.tag_id = 1)

...そして、含めたいタグの数だけ、同じ内部結合パターンでチェーンするだけです。少しかさばるかもしれませんが、ユーザーは先に進む前に 4 つまたは 5 つ以上のタグを選択することはないので、それで十分です。

同じ方法で除外し、すべてを 1 つのクエリにラップできることを本当に望んでいました。

INNER JOIN tag_item_assoc AS tia2 ON (tia2.item_id = i.item_id AND tia2.tag_id!= 2)

しかし、うまくいかないことがすぐに明らかになりました。s を使用すると、含めている間は除外できるという記事をいくつか読みましたが、ほとんどの場合、節LEFT OUTER JOINがばらばらであるために、それらを理解できませんでした。私が試したs とs のWHERE順列は、エラーが発生するか、非常に紛らわしい結果になりました。LEFT OUTER JOININNER JOIN

つまり、これを達成する方法を知っている人はいますか? 提供できる有用なコード例がないことをお詫びします。s が障害になる場合は、ゼロから始めても問題INNER JOINありません。複数の関連付けの包含と除外を同時に達成する方法が必要なだけです。助けと専門知識を前もってありがとう!

4

3 に答える 3

0

レコードのインスタンスの数をタグの数と一致させる必要があります。

SELECT a.item_id -- , add other columns here
FROM   items a
          INNER JOIN item_tag_assoc b
             ON a.item_id = b.item_id
WHERE b.tag_id IN (1, 2, 3) AND
      b.tag_id NOT IN (4, 5, 6)
GROUP BY a.item_id
HAVING COUNT(a.item_id) = 3
于 2012-08-13T07:49:56.090 に答える
0
SELECT a.*
FROM items a
     INNER JOIN item_tag_assoc b
         ON a.item_id = b.item_id
     INNER JOIN tags c
         ON a.tag_id = c.tag_id
WHERE c.tag_id IN(1) AND
      c.tag_id IN(2) AND
      c.tag_id IN(3) AND
      c.tag_id NOT IN (4) AND
      c.tag_id NOT IN (5) AND
      c.tag_id NOT IN (6) ;
于 2012-08-13T07:52:06.307 に答える
0

答えを見つけました。INNER JOIN次のように sを追加する代わりに:

INNER JOIN tag_item_assoc AS tia2 ON (tia2.item_id = i.item_id AND tia2.tag_id!= 2)

単一の内部結合を持つサブクエリを追加しました:

WHERE i.item_id NOT IN ( SELECT i.item_id FROM items AS s INNER JOIN tag_item_assoc AS tia1 ON (tia1.item_id = i.item_id AND tia1.tag_id IN (4, 5, 6)))

itemサブクエリは、[4、5、6] のいずれかのタグを持つすべての のセットを作成し、WHERE i.iten_id NOT INそのセットに一致するすべてのレコードを削除します。

努力してくれてありがとう!うまくいけば、これは将来誰かを助けるでしょう。

于 2012-08-13T18:20:41.380 に答える