2011-02-09 5 views
2

特定のタグを含むすべての投稿を選択したいと思います。私はこのクエリでそれをしようとしている:sql join problem

SELECT GROUP_CONCAT(t.tag_name) taglist 
FROM posts p 
JOIN posts_tags pt ON p.post_id = pt.post_id 
JOIN tags t ON t.tag_id = pt.tag_id 
WHERE (p.post_private = 0) AND t.tag_name = 'php' 
GROUP BY p.post_id 

問題があり、上記のクエリは、phpタグを含むすべての記事を選択するが、ポストが含まれていてもよい他のタグのいずれかを選択しません。 AND t.tag_name = 'php'の部分がないと、投稿ごとにタグを選択しますが、タグでフィルタリングできるようにしたいのですが...

どのようにすればいいですか?

|| *taglist* || 
|| php  || 

何:AND文で

|| *taglist* || 
|| php,echo || 
|| c++, cout || 

サンプルデータ:私はAND声明なし...

サンプル・データを多くのことを試してみたが、それを把握することはできません私は欲しい:

|| *taglist* || 
|| php,echo || 

(PHPタグを含む投稿o nly)

+0

(サブクエリと同様に作用する)JOINをしますか?あなたはそれがあなたが望んでいると確信していますか? –

+0

あなたは正しいですが、私はここでその必要はありませんが、まだ動作しません – networkprofile

+0

サンプルデータと期待される出力は何ですか? –

答えて

3
SELECT p.post_id, GROUP_CONCAT(t.tag_name) taglist 
    FROM posts p 
     /* These 2 joins get the list of all tags */ 
     INNER JOIN posts_tags pt 
      ON p.post_id = pt.post_id 
     INNER JOIN tags t 
      ON pt.tag_id = t.tag_id 
     /* These 2 joins guarantee the 'php' tag is included */ 
     INNER JOIN posts_tags pt2 
      ON p.post_id = pt2.post_id 
     INNER JOIN tags t2 
      ON pt2.tag_id = t2.tag_id 
       AND t2.tag_name = 'php' 
    WHERE p.post_private = 0 
    GROUP BY p.post_id 
+0

ありがとう、私はそれを見つけたとは思わない。下の2つの結合の仕組みはまだ分かりません。 – networkprofile

+0

+1はサブクエリを使用せず、INNER JOINのみです。 –

+1

@スリング:下の2つのジョインは、最初の2つと同じですが、条件には 'AND t2.tag_name = 'php'も含まれています。 INNER結合であるため、返される投稿にはPHPタグが関連付けられている必要があります。 –

2

最初の試行がうまくいかない理由を説明しようとします。

あなたが本当にやろうとしているのは、のタグのうちが「php」である投稿をすべて見つけることです。 しかし、それらのタグはの多くの行に広がっていますので、t.tag_name = 'php'は 'php'タグを持たないすべての行を除外して動作しません。あなたは多くの行に依存して状態を確認したい

あなたのいずれか

p.post_id IN 
    (SELECT pt2.post_id 
     FROM post_tags pt2 
     JOIN tags t2 
      ON t2.tag_id = pt2.tag_id 
     WHERE t2.tag_name = 'php' 
) 

(PHPタグを持っているすべてのpost_idsを見つけるために)まだでこれらpost_idsに参加サブクエリを作成しますすべての関連タグ。

SELECT GROUP_CONCAT(t.tag_name) taglist 
    FROM posts p 
    JOIN posts_tags pt 
     ON p.post_id = pt.post_id 
    JOIN tags t 
     ON t.tag_id = pt.tag_id 
    WHERE (p.post_private = 0) 
    AND p.post_id IN 
     (SELECT pt2.post_id 
      FROM post_tags pt2 
      JOIN tags t2 
       ON t2.tag_id = pt2.tag_id 
      WHERE t2.tag_name = 'php' 
    ) 
    GROUP BY p.post_id 

それとも、それはもう少し賢くステファネッリが2以上で示したようRIGHT JOINの

+0

私は、説明するために迷惑を取っていただきありがとうございます! – networkprofile