2009-03-16 14 views
1

私は可能な限り私のケースを説明しようとします。 私はタグを参照してトピックを見つけることができるウェブサイトを作っています。そこには奇妙なことはありません。私はいくつかのクエリで厄介な時間を過ごしています。彼らはあなたのために簡単かもしれない、私の心は仕事の多くをやることからかなり台無しです:P。別のテーブルと同じリレーションを持つテーブルからフィールドを取得します

私はテーブル "topics"と "tags"を持っています。これらは、topic_idとtag_idを含むtags_topicsテーブルを使用して結合されます。ユーザーがトピックを見つけたい場合は、最初にフィルタするタグを1つ選択してから、もう1つをフィルタに追加します。次に、選択したタグの両方を持つすべてのトピックを取得するためのクエリを作成します。彼らはまた、他のタグを持っているかもしれませんが、それらがフィルタリングするために選択されたタグを持っていなければなりません。フィルタリングするタグの量は異なりますが、フィルタリングするユーザーが選択したタグのリストは常にあります。 これは主にFiltering from join-tableで答えられました。私は複数の結合ソリューションを使いました。

これで、ユーザーがフィルタリングできるタグを取得する必要があります。したがって、すでに2つのタグの定義済みフィルタがある場合は、フィルタ内のすべてのタグを含むトピックに関連付けられたタグをすべて取得する必要があります。私は実践的な例を挙げます:P

テニス、ジム、ゴルフの3つのトピックがあります。

  • テニスのタグがあります:スポーツ、ボール、コート、ラケットを
  • ジムにはタグがあります:スポーツ、トレーニングや筋肉
  • ゴルフのタグがあります:スポーツ、ボール、スティックと外

    1. をユーザーはタグスポーツを選択するので、3つのテニス、ジム、ゴルフをすべて表示し、可能な他のフィルタとしてボール、コート、ラケット、トレーニング、筋肉、スティック、アウトを表示します。
    2. これで、ボールにフィルタが追加されるようになりました。フィルタはスポーツとボールになっていますので、テニスとゴルフのトピックを、裁判所、ラケット、スティック、アウトドアを追加のフィルタとして表示します。
    3. ユーザーがフィルタに裁判所を追加するようになりました。追加のフィルタとしてテニスとラケットを表示します。

私はなんらかの意味があると思います。ところで、私はMySQLを使用しています。

+0

「他のタグの集まり」ではないタグ1、タグ2、タグ3を特別なものにする理由は不明です。残りは必要ではないのになぜ必要なのですか?これをどうやって知っていますか?それは私たちが仮定できるタグの定義済みのリストですか? – chaos

+0

テーブル構造をいくつか与え、その質問をより詳しく説明したいと思うかもしれません。私はあなたが望むものを手に入れたと思うが、理解する前にそれを5回読んだ。 – achinda99

+0

http://stackoverflow.com/questions/648308/filtering-from-join-tableの正確な複製 –

答えて

0
SELECT DISTINCT `tags`.`tag` 
FROM `tags` 
LEFT JOIN `tags_topics` ON `tags`.`id` = `tags_topics`.`tag_id` 
LEFT JOIN `topics` ON `tags_topics`.`topic_id` = `topics`.`id` 
LEFT JOIN `tags_topics` AS `tt1` ON `tt1`.`topic_id` = `topics`.`id` 
LEFT JOIN `tags` AS `t1` ON `t1`.`id` = `tt1`.`tag_id` 
LEFT JOIN `tags_topics` AS `tt2` ON `tt2`.`topic_id` = `topics`.`id` 
LEFT JOIN `tags` AS `t2` ON `t2`.`id` = `tt2`.`tag_id` 
LEFT JOIN `tags_topics` AS `tt3` ON `tt3`.`topic_id` = `topics`.`id` 
LEFT JOIN `tags` AS `t3` ON `t3`.`id` = `tt3`.`tag_id` 
WHERE `t1`.`tag` = 'tag1' 
AND `t2`.`tag` = 'tag2' 
AND `t3`.`tag` = 'tag3' 
AND `tags`.`tag` NOT IN ('tag1', 'tag2', 'tag3') 
+0

ありがとう、 "単純な"ソリューションのように見えます。サブクエリを実行するよりパフォーマンスが向上します。 – finpingvin

+0

はい、ただしタグは3つまでです。 –

+0

しかし、アプリケーションコード – finpingvin

0
SELECT topic_id 
FROM  topic_tag 
WHERE tag_id = 1 
     OR tag_id = 2 
     OR tag_id = 3 
GROUP BY topic_id 
HAVING COUNT(topic_id) = 3; 

上記のクエリは1、2と3の3つのすべてのtag_idsを持っているすべてのtopic_idsが続いサブクエリとしてこれを使用するでしょう:

SELECT tag_name 
FROM tag 
     INNER JOIN topic_tag 
ON  tag.tag_id = topic_tag.tag_id 
WHERE topic_id IN 
        (SELECT topic_id 
        FROM  topic_tag 
        WHERE tag_id = 1 
          OR tag_id = 2 
          OR tag_id = 3 
        GROUP BY topic_id 
        HAVING COUNT(topic_id) = 3 
        ) 
    AND 
     (
       tag.tag_id <> 1 
      OR tag.tag_id <> 2 
      OR tag.tag_id <> 3 
     ) 

私は、これはあなたが探しているものだと思います。

+0

INを使用する代わりに、内部結合を行うことができますが、その後、特定の列の名前を変更する必要があり、私は怠け者です。 – achinda99

0
Select a.topic_id 
    from join_table a 
where exists(select * 
       from join_table b 
       where a.tag_id = b.tag_id 
        and b.topic_id = selected_topic) 
group by a.topic_id 
having count(*) = (select count(*) 
         from join_table c 
         where c.topic_id = selected_topic) 

あなたselected_topicのためにすべてのタグを持っているトピックのリストを与える必要があります。

0

ジェネリック私の頭の上からソリューションが、タイプミスを持ってする傾向:

CREATE VIEW shared_tags_count AS 
    SELECT topic_to_tag1.topic_id AS topic_id1, topic_to_tag2.topic_id AS topic_id2, COUNT(*) as number 
    FROM topic_to_tag as topic_to_tag1 
     JOIN topic_to_tag as topic_to_tag2 
     ON topic_to_tag1.topic_id <> topic_to_tag2.topic_id 
      AND topic_to_tag1.tag_id = topic_to_tag2.tag_id 
GROUP BY topic_to_tag1.topic_id, topic_to_tag2.topic_id; 

    CREATE VIEW tags_count AS 
    SELECT topic_id, COUNT(*) as number 
    FROM topic_to_tag 
GROUP BY topic_id 

CREATE VIEW related_topics AS 
SELECT shared_tags_count.topic_id1, shared_tags_count.topic_id2 
    FROM shared_tags_count 
     JOIN tags_count 
     ON topic_id=topic_id1 
      AND shared_tags_counts.number = tags_count.number 

CREATE VIEW related_tags AS 
SELECT related_topics.topic_id1 as topic_id, topic_to_tag.tag_id 
    FROM related_topics 
     JOIN topic_to_tag 
     ON raleted_topics.tag_id2 = topic_to_tag.topic_id 

はあなただけrelated_tagsビューを照会する必要があります。

興味深いチャレンジbtw。

+0

でクエリを動的に構築することができます。複雑に見えます:P – finpingvin

+0

は主にテーブル名のためです;)私は問題をビューに分割するのが好きです。スキルを変更したときにコードを増やすことはできますが、維持しやすくなります。 –

+0

はい、私はそれを見ることができます:)私は実際にビューを使用したことはない、私はそれを見てみる必要があります。 – finpingvin

関連する問題