2009-03-06 1 views
1

私はこれが効率的に行うことが可能ですが、ここでは私の問題だとしてもよく分からない:困難な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 

答えて

1

誰かが投稿にコメントを付けるとblog_post_idとblog_comment_idの両方に記入すると、次のSQLがそのトリックを行うはずです。 ここでは、Tag.nameは一意であると仮定しています。あなたが探して何

SELECT MIN(ts.tag_id), t.name, COUNT(ts.blog_post_id) as rank 
FROM Taggings ts 
    INNER JOIN Tags t ON ts.tag_id = t.id 
GROUP BY t.name 
ORDER BY COUNT(ts.blog_post_id) DESC 

希望。

+0

COUNT(blog_post_id)は1とCOUNT(blog_comment_id)であるので、私は、ブログのコメントにタグを付けたときに2のタグ数を返すこと1. –

+0

許がある - が、私は「+ COUNT(blog_comment_id)」の部分を取るならば、それは私が望んでいた、まさに私を与えると思います。 クール!私はそれがまったく悪くないと思う。ありがとう。 –

+0

あなたはコメントと投稿の両方を数えたいと思ったのですが?私はあなたを誤解しているかもしれません。 – Tomalak

0

私が欠落している可能性がありこれまでのところ、私はあなたの要求が複雑に何も表示されません

0

私がしようとしたが、どのようなこのような何かについていなかった?:

select t.Id, 
    t.Name, 
    count(*) 

from Taggings tings 
inner join Tags t 
    on (t.id = tings.blog_post_id or t.id = tings.blog_comment_id) 

group by t.Id, t.Name 
order by count(*) desc