【问题标题】:Counting number of positive and negative votes:统计正负票数:
【发布时间】:2011-04-20 22:11:42
【问题描述】:

我有以下表格:

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

Value 是一个 tiny_int,可以是 1 或 -1。

我要统计每个帖子的正负票数:

$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) 缓存?

【问题讨论】:

  • sql_select 返回什么?这个函数有文档吗?
  • 在您当前的 SQL 中,您使用的是 SUM,而实际上您可以使用 COUNT 来产生更快的结果。
  • sql_select 是我自己做的一个函数,如果sql查询不正确(即无法执行选择)会抛出异常

标签: php mysql voting


【解决方案1】:

您可以在单个查询中进行计数:

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

如果您想组合您的第一个查询和第二个查询,您可以获得:

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

【讨论】:

  • 如何将它与第一个查询结合起来?所以我可以选择与每个帖子相关的所有帖子和投票。
  • @jonnnnnnnnnie - 您只需将此查询填充到派生表中。我已经扩展了我的答案来说明。
【解决方案2】:

我找不到您正在使用的函数sql_select(),但您最好在SQL 中使用count(*) 而不是尝试sum()。您只需要计算它看起来像的行,而不是对这些值求和。你也可以更高级一点,使用 GROUP BY:

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

这将为每个唯一值返回一行。返回的每一行都将报告唯一值和使用该值的行数。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2023-03-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多