我正在创建一个类似于stackoverflow的应用程序,因为它有问题和答案的评级,我也有标签显示最早,最新和投票的评论。我无法按投票排序。
这是我的功能:
/**
*
* @param int $threadid
* @param string $tab
* @param object $voting referencing Voting.class.php (may not be needed)
* @return database query/array
*/
public function getComments($threadid, $tab = 'oldest', $voting = null) {
if ($tab == 'oldest') {
$sql = "SELECT * FROM comments WHERE threadid = :threadid ORDER BY date ASC";
} else if ($tab == 'newest') {
$sql = "SELECT * FROM comments WHERE threadid = :threadid ORDER BY date DESC";
} else if ($tab == 'votes') {
//i dont know what to do here? read below for more explanation
} else {
$sql = "SELECT * FROM comments WHERE threadid = :threadid ORDER BY date ASC";
}
$stmt = $this->db->prepare($sql);
$stmt->bindParam(':threadid', $threadid);
$stmt->execute();
$row = $stmt->fetchAll(PDO::FETCH_ASSOC);
return $row;
}
这是我的数据库设计:
**comments:** | id | userid | threadid | message | date |
**commentsrating:** | userid | commentid | voteup | votedown |
如果评级与评论分开,则可以对符合其余代码的$tab == 'votes'
进行查询吗?
最后是HTML:
<?php //Get comments
if (isset($_GET['tab'])) {
$getComments = $thread->getComments($threadid, $_GET['tab'], $voting);
} else {
$getComments = $thread->getComments($threadid);
} ?>
<?php for ($i = 0; $i < count($getComments); $i++) { ?>
<p>
<?php echo $getComments[$i]['message']; ?>
</p>
<p>
<span class="bid_votes_count" id="bid_votes_count<?php echo $getComments[$i]['id'] ?>">
<?php echo $voting->getEffectiveCommentVotes($getComments[$i]['id']) . " votes"; ?>
</span>
<span class="bid_vote_buttons" id="bid_vote_buttons<?php echo $getComments[$i]['id'] ?>">
<a href="javascript:;" class="bid_vote_up" id="<?php echo $getComments[$i]['id'] ?>"></a>
<a href="javascript:;" class="bid_vote_down" id="<?php echo $getComments[$i]['id'] ?>"></a>
</span>
</p>
<?php } ?>
Thanks in advance!
答案 0 :(得分:3)
将rating
字段添加到comments
表格并手动维护或使用commentsrating
表格上的触发器进行维护。
显然,将预先计算的评级值放在那里,现在你可以有一个简单而可怕的快速问题来执行。
答案 1 :(得分:1)
试一试:
$sql = "SELECT * FROM comments c JOIN (SELECT commentid, ".
"(SUM(voteup) - SUM(votedown)) votes, " .
"FROM commentsrating GROUP BY commentid) i ON " .
"c.id = i.commentid WHERE c.threadid = :threadid " .
"ORDER BY i.votes DESC";
显然不是疯狂JOIN的最佳表现,但应该让你“有效”,之后你可以担心性能。
答案 2 :(得分:1)
最快的方法是将投票的运行记录存储在评论表中作为字段(如另一个答案中所述)。但是,您还应该考虑修改评论表以使其更有意义,并帮助解决统计问题。
评论: | userid | commentid |投票|
您应该只有投票的原因是评论评分只能进行一次投票。它不能同时进行投票和投票。
投票应为int(1)+/-。例如。可以是1或-1(理论上为0)。这样您就可以执行以下SQL:
SELECT c.id, c.message, c.date, SUM(cr.vote) AS 'votes'
FROM `comments` c
JOIN `commentsrating` cr ON c.id=cr.commentid
WHERE c.threadid=':threadid'
GROUP BY c.id
ORDER BY `votes`
查询将花费比order by
total_votes字段更长的时间,但无论如何都应该这样做。
答案 3 :(得分:0)
SELECT * FROM `comments` WHERE `threadid`=:threadid ORDER BY (SELECT `voteup`-`votedown` FROM `commentsrating` WHERE `commentid`=`comments`.`id`) DESC
试试吗?