5

次のテーブルがあります。

post (id, title, content) etc
author (id, username) etc
author_vote (post_id, author_id, value)

値は、1 または -1 のいずれかの tiny_int です。

各投稿の賛成票と反対票の数を数えたい:

$posts = sql_select($link, "SELECT post.*, author.username 
                            FROM post, author 
                            AND author.id = post.author_id");

次のコードが機能しないのはなぜですか?

array_walk($posts, function(&$post, $link){
   $post['positive'] = sql_select($link, "SELECT SUM(value) FROM author_vote WHERE post_id = $post['id']
                                            AND value  = 1");

   $post['negative'] = abs(sql_select($link, "SELECT SUM(value) FROM author_vote WHERE post_id = $post['id']
                                            AND value  = -1"));
});

私も次のことを試しました。これにより、すべての投票が各投稿で同じになります。

foreach ($posts as &$post)
{
   $id = $post['id'];
   $post['positive'] = (int)sql_select($link, "SELECT SUM(value) FROM author_vote WHERE post_id = $id
                                           AND value  = 1");
   $post['negative'] = (int)abs(sql_select($link, "SELECT SUM(value) FROM author_vote WHERE post_id = $id
                                               AND value  = -1"));
}

また、投稿ごとにデータベースに複数回クエリを実行することなくこれを行う方法はありますか? [このように] 絶えず変化しているものを (mem)cached にするにはどうすればよいでしょうか?

4

2 に答える 2

5

単一のクエリでカウントを実行できます。

Select Sum( Case When value < 0 Then 1 Else 0 End ) As NegVotes
    , Sum( Case When value > 0 Then 1 Else 0 End ) As PosVotes
From author_vote
Where post_id = ...

投稿ごとに賛成票と反対票が必要な場合:

Select post_id
    , Sum( Case When value < 0 Then 1 Else 0 End ) As NegVotes
    , Sum( Case When value > 0 Then 1 Else 0 End ) As PosVotes
From author_vote
Group By post_id

最初のクエリと 2 番目のクエリを結合したい場合は、次を取得できます。

Select post....
    , author.username 
    , Coalesce(post_count.NegVotes,0) As NegVotes
    , Coalesce(post_count.PosVotes,0) As PosVotes
From post
    Join author
        On author.id = post.author_id
    Left Join   (
                Select post_id
                    , Sum( Case When value < 0 Then 1 Else 0 End ) As NegVotes
                    , Sum( Case When value > 0 Then 1 Else 0 End ) As PosVotes
                From author_vote
                Group By post_id
                ) As post_count
        On post_count.post_id = post.post_id
于 2011-04-20T22:25:55.033 に答える
0

sql_select()使用している関数が見つかりませんがcount(*)sum(). 値を合計するのではなく、見える行を数えるだけです。GROUP BY を使用して、もう少し手の込んだものにすることもできます。

SELECT value, count(value) AS value_count FROM author_vote WHERE post_id = $id GROUP BY value

これにより、一意の値ごとに 1 行が返されます。返される各行は、一意の値とその値を使用する行の数を報告します。

于 2011-04-20T22:24:41.540 に答える