私はこれが効率的に行うことが可能ですが、ここでは私の問題だとしてもよく分からない:困難なSQLクエリ:複雑な団体とモデルのためのタグ人気
私は基本的にブログの記事ブログエンジン何書いています各ブログ投稿へのすべての返信にタグを付けることができます。
だから、私はブログの記事は、「スタック」をタグ付け、およびそのポストへの返信は「オーバーフロー」タグの付いた可能性があります。今
、私は、ユーザーが自分のアプリケーションに特別なページに当たったとき、最も人気のあるタグのリストを生成しようとしています。これは、ブログの記事の数を降順でn個だけではなく、最も人気のあるタグを返しますが、必要があり、各タグに関連するブログ記事の数、そのポストで返信ではなく、ポスト自体がそのタグでタグ付けされている場合でも。
BlogPost Aに「foo」というタグが付けられていて、BlogPost Bの返信に「foo」というタグが付いている場合、BlogPost Bが技術的にそうではなくても、タグ付き。
ここでは、関連するかもしれないテーブル/フィールドの説明です:
BlogPosts
| id # Primary key for all tables, Rails-style
BlogComments
| id
| blog_post_id
Tags
| id
| name # 'foo'
Taggings
| id
| tag_id
| blog_post_id
| blog_comment_id
便宜上タギングでは、いくつかの非正規化があります。誰かがBlogPostにタグを付けると、それはblog_post_idフィールドに入り、blog_comment_idはNULLのままです。誰かが投稿にコメントを付けると、blog_post_idとblog_comment_idの両方に書き込まれます。
一つまたは複数のSQLクエリの中で最も人気のあるタグのソートされたリストを返すために、いくつかの方法はありますか?私は...私はちょうどcronジョブの数分ごとに計算上高価なスクリプトを実行して、代わりにこれを誰かがページをヒットするたびに実行されているのキャッシュされた出力をレンダリングする必要があるかもしれません
感謝を考えています!あなただけの「影響を受けたブログの記事を」カウントしたい場合は、私はそれは方法だと思う
SELECT
tag_id,
COUNT(blog_post_id) + COUNT(blog_comment_id) tag_count
FROM
Taggings
GROUP BY
tag_id
ORDER BY
COUNT(blog_post_id) + COUNT(blog_comment_id) DESC
:
SELECT
t.id tag_id,
t.name tag_name,
COUNT(DISTINCT COALESCE(x.blog_post_id, c.blog_post_id)) tag_count
FROM
Tags t
INNER JOIN Taggings x ON x.tag_id = t.id
LEFT JOIN BlogComments c ON c.id = x.blog_comment_id
GROUP BY
t.id,
t.name
ORDER BY
COUNT(DISTINCT COALESCE(x.blog_post_id, c.blog_post_id)) DESC
COUNT(blog_post_id)は1とCOUNT(blog_comment_id)であるので、私は、ブログのコメントにタグを付けたときに2のタグ数を返すこと1. –
許がある - が、私は「+ COUNT(blog_comment_id)」の部分を取るならば、それは私が望んでいた、まさに私を与えると思います。 クール!私はそれがまったく悪くないと思う。ありがとう。 –
あなたはコメントと投稿の両方を数えたいと思ったのですが?私はあなたを誤解しているかもしれません。 – Tomalak