我想选择帖子上发布的总评论。不知何故,我能够做到,但问题是即使帖子上没有评论,总评论也会显示在每个帖子下。
问题:无法获得与发布相关的评论。
我想要的是什么:
选择与每个帖子相关的总评论。
我尝试了什么:
SELECT SUM(total_comment) AS comment
FROM user_comment
INNER JOIN post
ON user_comment.image_id = post.id
WHERE status = 0
SELECT SUM(total_comment) AS comment
FROM user_comment
WHERE status = 0
这两个查询都会返回所有帖子的所有(总)评论,但我只想显示与特定帖子相关的评论。
结果看起来像
OR
但我想要
OR
更新
我认为大多数人都不明白我想问的是什么?所以我发布了index.php代码,我使用while循环从数据库访问数据,在index.php页面上我想访问特定帖子上发布的总评论。
的index.php
<?php
session_start();
include 'conn.php';
if(!isset($_SESSION['user']))
{
header('location:signin.php');
}
$smt=$conn->prepare("SELECT * FROM post,images WHERE post.Id=images.Id");
$smt->execute();
$smtt=$conn->prepare("SELECT * FROM post");
$smtt->execute();
$myres=$smtt->fetch(PDO::FETCH_OBJ);
$imgid=$myres->Id;
$imgname=$myres->File_Name;
$qry=$conn->prepare("SELECT SUM(Total_Comment) AS comment FROM user_comment WHERE Image_Id='".$imgid."' AND Image_Name='".$imgname."'");
$qry->execute();
$result=$qry->fetch(PDO::FETCH_OBJ );
$total_coment=$result->comment;
?>
<?php include 'header.php';?>
<?php
if(isset($_SESSION['user']))
{
include 'nav.php';
}
else
{
include 'nav-simple.php';
}
?>
<div class="container-fluid">
<?php include 'right_sidebar.php';?>
<div class="main-container-top" id="masonry-grid">
<?php while($rows=$smt->fetch(PDO::FETCH_OBJ)): ?>
<div class="col-md-3 grid-item post-col">
<img src="image/<?php echo $rows->Image_Name;?>" data-echo="image/<?php echo $rows->Image_Name;?>" class="post-image"/>
<h5>Post On <?php echo $rows->Post_Date;?> <span class="pull-right">By <?php echo $rows->Post_By; ?></span> <span class="pull-right">Total Comment <?php echo $total_coment;?></span></h5>
<a href="post-description.php?id=<?php echo $rows->Id ?>"> <h4><?php echo $rows->Post_Title;?></h4> </a>
<p>
<?php echo $rows->Post;?>
</p>
</div>
<?php endwhile;?>
</div>
</div>
<?php include 'footer-content.php';?>
<?php include 'footer.php';?>
更新2
我知道为什么查询在每个帖子下显示2或3的原因是原因是查询从表中选择第一个或第二个id并计算/求和它,但我无法解决问题,因为我想要在每篇文章下发表评论,而不是在所有帖子下发表一条评论。
注意:
当我在后期描述页面上运行查询时,它会正常工作,但我想在index.php页面上显示每篇帖子的总评论数...
我的post-description.php代码
<?php
session_start();
include 'conn.php';
$pic_id='';
if(isset($_GET['id']))
{
$pic_id=$_GET['id'];
}
$comv=$conn->prepare("SELECT * FROM user_comment WHERE user_comment.Image_Id='".$pic_id."' AND user_comment.Status=0 AND user_comment.Comment_Status=1");
$comv->execute();
$fimg=$conn->prepare("SELECT Image_Name From Images WHERE Id='".$pic_id."'");
$fimg->execute();
$gimg=$fimg->fetch(PDO::FETCH_OBJ);
$pro=$conn->prepare("SELECT Profile_Picture FROM user_registration WHERE User_Name='".$_SESSION['user']."'");
$pro->execute();
$prof_img=$pro->fetch(PDO::FETCH_OBJ);
$smt=$conn->prepare("SELECT * FROM post,images WHERE post.Id = images.Id AND post.Id='".$pic_id."'");
$smt->execute();
$qry=$conn->prepare("SELECT COUNT(Total_Comment) AS comment FROM user_comment WHERE Status=0 AND Image_Id ='".$pic_id."'");
$qry->execute();
$result=$qry->fetch(PDO::FETCH_OBJ );
$total_coment=$result->comment;
?>
<?php include 'header.php';?>
<?php include 'nav.php';?>
<div class="container-fluid">
<?php include 'right_sidebar.php';?>
<div class="col-md-1"></div>
<div class="col-md-9 main-container-top container">
<?php while($rows=$smt->fetch(PDO::FETCH_OBJ)):?>
<div class="media col-md-12 description-post">
<img src="image/<?php echo $rows->Image_Name;?>" alt="<?php echo $rows->Image_Name;?>" class="img-rounded img-responsive media-left img-description"/>
<div class="media-body">
<h4 class="h4 description-heading"><?php echo $rows->Post_Title;?> <small class="pull-right"><i class="fa fa-comments-o fa-2x"></i> <?php echo $total_coment;?></small></h4>
<p class="post-text text-justify text-info">
<?php echo $rows->Post;?>
</div>
<?php endwhile;?>
</div>
<br/>
<div class="media col-md-12 comment-section">
<?php
if(isset($_SESSION['comment-error']))
{
?>
<span class="alert alert-warning col-md-6 container col-md-offset-3"><?php echo $_SESSION['comment-error']; ?></span>
<?php
}
unset($_SESSION['comment-error']);
if(isset($_SESSION['comment-success']))
{
?>
<span class="alert alert-success col-md-6 container col-md-offset-3"><?php echo $_SESSION['comment-success']; ?></span>
<?php
}
unset($_SESSION['comment-success']);
?>
<br/>
<?php while($gcom=$comv->fetch(PDO::FETCH_OBJ)):?>
<span class="col-md-1 comment-pic"><img src="profile%20picture/<?php echo $gcom->Profile_Picture;?>" alt="post image" class="img-thumbnail img-responsive comment-img"/></span>
<div class="media-body comment-head col-md-10">
<h6 class="h6"><a href="#"> <?php echo $gcom->User_Name;?> </a> on <?php echo $gcom->On_Time;?></h6>
<p class="comment"><?php echo $gcom->Comment;?></p>
</div>
<?php endwhile;?>
</div>
<br/>
<div class="col-md-12 container">
<h4 class="description-heading h4 text-muted">Share your thought</h4>
<br/>
<form action="comment.php" method="post" class="col-md-12" id="commentForm">
<textarea name="comment" id="" cols="100" rows="5" placeholder="Your comment"></textarea>
<input type="hidden" name='picture-name' value="<?php echo $gimg->Image_Name;?>"/>
<input type="hidden" name="profile-pic" value="<?php echo $prof_img->Profile_Picture;?>"/>
<input type="hidden" name="pic-id" value="<?php echo $pic_id;?>"/>
<input type="hidden" name="image-id" value="<?php echo '?id='.$pic_id;?>"/>
<br/>
<input type="submit" value="Post" name="cmsg" id="" class="btn btn-info"/>
<br/>
</form>
</div>
<br/>
</div>
</div>
<?php include 'footer-content.php';?>
<?php include 'footer.php';?>
答案 0 :(得分:2)
如果你为你回来的每个帖子运行一个单独的查询,这就是你想要做的事情,我们只是根据你发布的两个查询进行猜测,这两个查询都返回一行...
要使用该模式,您需要在WHERE
子句中添加一个附加谓词,以识别哪个 post
您想要返回评论计数。例如:
SELECT SUM(c.total_comment) AS comment
FROM user_comment c
WHERE c.status = 0
AND c.image_id = 2
如果给定的image_id
没有行,则SUM()
聚合将返回NULL。您可以在代码中处理它,并将其转换为零,或者您可以在SQL中处理它,以便它将返回零而不是NULL。您可以使用方便的IFULL()
功能...
SELECT IFNULL(SUM(c.total_comment),0) AS comment
FROM user_comment c
WHERE c.status = 0
AND c.image_id = 2
如果IFNULL函数的第一个参数为NULL,则该函数返回第二个参数,否则返回第一个参数。
IFNULL(a,b)
是ANSI
的特定于MySQL的简写CASE WHEN a IS NULL THEN b ELSE a END
这回答了你问的问题。如何计算特定职位。
这里的其他答案正在解决这种方法的问题...为每个帖子运行单独的查询并不是最有效或最具可扩展性的设计。
每个查询执行都需要往返数据库,数据库必须解析SQL文本,检查语法是否有效,进行语义检查,字典查找以验证标识符是否有效,数据库用户是否具有所需权限权限,决定执行计划,然后运行查询,准备结果集并返回给调用者。而且这种开销加剧了。
这里的其他一些答案正在解决。他们不是为每个image_id
运行单独的查询,而是一举得到计数。他们通过将image_id
列添加到SELECT列表并向查询添加GROUP BY image_id
来执行此操作...以返回此类结果
image_id comment
-------- -------
2 3
5 2
那会让你回到所有的非零数。但是......你不会在从post表中获取行的循环中运行它...你首先运行这个查询,然后将结果存储到一个数组中,然后对于你正在放置的每个帖子在页面中,您将进行数组查找以查找计数。如果找不到,则计数为零。
您还可以返回零计数,并使用以下查询存储这些计数:
SELECT p.id
, IFNULL(SUM(total_comment),0) AS comment
FROM post p
LEFT
JOIN user_comment c
ON c.image_id = p.id
AND c.status = 0
GROUP BY p.id
但那只是额外的行,零,仍然是一个数组查找,唯一的区别是你会找到一个匹配...真的没有什么不同。
但是......你真的不想这样做。
查询真正提示的是,您不需要 SEPRATE 查询来获取评论计数;您可以在 SAME QUERY 中获取该内容,该内容将返回post
中的行。
只需将外连接添加到user_comment
表,在GROUP BY
表中的唯一标识符上添加post
子句,并将该聚合SUM()表达式返回到SELECT列表,以及您从post
表转向的列。例如:
SELECT p.id
, p.Post_Title
, p.Post
, p.Filename
, p.Tag
, p.Post_Date
, p.Post_By
, IFNULL(SUM(c.total_comment),0) AS comment
FROM post p
LEFT
JOIN user_comment c
ON c.image_id = p.id
AND c.status = 0
GROUP BY p.id
ORDER BY p.Post_Date DESC, p.id DESC
这通常是一种更具伸缩性的设计,可以在单个查询中返回结果,而不是运行大量单独的查询。
另一种选择,通常不如外连接那么高效,是在SELECT列表中使用相关子查询:
SELECT p.id
, p.Post_Title
, p.Post
, p.Filename
, p.Tag
, p.Post_Date
, p.Post_By
, ( SELECT IFNULL(SUM(c.total_comment),0)
FROM user_comment c
WHERE c.image_id = p.id
AND c.status = 0
) AS comment
FROM post p
ORDER BY p.Post_Date DESC, p.id DESC
或者,我们也可以对内联视图使用外连接操作(但是在更一般的情况下,当涉及更多连接时,这更适用,并且我们不希望加倍或三重计数,尽管它在这种情况下会返回相同的结果(假设id
表中post
是唯一的),
SELECT p.id
, p.Post_Title
, p.Post
, p.Filename
, p.Tag
, p.Post_Date
, p.Post_By
, IFNULL(t.total_comment,0) AS comment
FROM post p
LEFT
JOIN ( SELECT c.image_id
, SUM(c.total_comment) AS total_comment
FROM user_comment c
WHERE c.image_id = p.id
GROUP BY c.image_id
) t
ON t.image_id = p.id
ORDER BY p.Post_Date DESC, p.id DESC
<强>后续强>
根据您发布的PHP代码,重点是......您只需要 SINGLE SQL语句。
只需为每个帖子返回派生的“total_comment”值,以及每个帖子行,只需修改查询(正如我在上面的回答中所指出的,有几种可能的方法来获得该结果。只需告诉数据库返回该值相信你。然后你的代码更简单。(为了更确定的结果,在查询中添加ORDER BY
子句。)
例如:
$sql="SELECT p.Id
, p.Post_Title
, p.Post
, p.Filename
, p.Post_Date
, p.Post_By
, IFNULL(SUM(c.total_comment),0) AS total_comment
FROM post p
LEFT
JOIN user_comment c
ON c.image_id = p.id
AND c.status = 0
GROUP BY p.id
ORDER BY p.Post_Date DESC, p.id DESC";
$stmt=$conn->prepare($sql);
$stmt->execute();
while($post = $stmt->fetch(PDO::FETCH_OBJ)):
echo "<hr>";
echo "<br>" . $post->Id;
echo "<br>" . $post->Post_Title;
echo "<br>" . $post->Post;
echo "<br>" . $post->Filename;
echo "<br>" . $post->Post_Date;
echo "<br>" . $post->Post_By;
echo "<br>" . $post->total_comment;
endwhile;
这是一个非常简单的示例,只是回显了返回的值,而没有实际想要输出的所有HTML。它用于演示您不需要使用第二个或第三个SQL语句来破解代码。
而且(显然)这个例子没有解决转义存储在数据库列中的潜在HTML字符,也没有解决PDO错误处理,setAttribute(PDO::ATTR_ERRORMODE,PDO::ERRMODE_EXCEPTION)
和适当的try / catch / finally块,或者添加单独检查prepare
和execute
来电的回报。省略了这些以避免模糊模式。
答案 1 :(得分:1)
SELECT SUM(Total_Comment) AS comment FROM user_comment INNER JOIN post ON user_comment.Image_Id = post.Id WHERE Status=0 GROUP BY post.Id
我相信group by
inner join
可以帮助您获得所需内容。
希望这会有所帮助。
答案 2 :(得分:0)
您需要left join
和group by
对于user_comment
表
SELECT IFNULL(SUM(Total_Comment),0) AS comments, post.Id FROM
post
LEFT JOIN user_comment
ON user_comment.Image_Id = post.Id
AND Status=0
group by post.Id
答案 3 :(得分:0)
如果我理解正确你想要这样的结果啊?
Post
totalCommand
Post
totalCommand
查询:
SELECT post
FROM (
SELECT post
,postid
,1 AS ord
FROM post
UNION ALL
SELECT convert(IFNULL(SUM(Total_Comment), 0), CHAR) AS post
,po.postid
,2 AS ord
FROM commenttable co
RIGHT JOIN posttable po ON po.postid = co.postid
GROUP BY po.postid
) AS tt
ORDER BY postid
,ord
答案 4 :(得分:0)
根据其他评论看起来,您已经忘记包含原始查询是在特定用户的评论总数之后。尝试将User_Name
添加到WHERE CLAUSE
,假设您的代码中某处包含@username
变量,但不包括:
SELECT SUM(Total_Comment) AS comment
, post.Id
FROM user_comment
INNER JOIN post ON user_comment.Image_Id = post.Id
WHERE Status=0
AND user_comments.User_Name = @username
GROUP BY post.Id
答案 5 :(得分:0)
以下是SQLFiddle上带有一些虚拟数据的示例。
但是这样的查询可以获得单个帖子的评论总数。
SELECT COUNT(*) FROM comments INNER JOIN posts ON comments.`Image_Name` = posts.`File_Name` WHERE comments.status = 0 AND comments.Image_Name = "956.jpg";
或者,如果您想获得每篇帖子的评论总数,您将执行以下查询:
SELECT comments.Image_name, COUNT(*) FROM comments INNER JOIN posts ON comments.`Image_Name` = posts.`File_Name` WHERE comments.status = 0 GROUP BY comments.Image_Name;
您可以使用COUNT()
代替SUM()
,而不再需要Total_Comment
列。作为建议,我建议在表之间使用更好的关系(使用ID)。显然,将“956.jpg”更改为您要检查的文件名,或更改要检查的列。
答案 6 :(得分:0)
我并不完全理解在评论表中使用'Total_comment'的目的,可以通过使用'COUNT()'轻松实现。为了简单起见,我将在我的示例中使用COUNT()。
SELECT
post.Id,
post.Post_Title,
post.Post,
post.File_Name,
post.Tag,
post.Post_Date,
post.Post_By,
COUNT(user_comment.id) AS total_post_comment
FROM
post
LEFT JOIN user_comment ON (user_comment.Image_Id=post.Id AND user_comment.Status=0)
GROUP BY
post.id
答案 7 :(得分:0)
这对我有用:
select p.*, ifnull(total_comments, 0)
from post p
left join (select image_id, SUM(total_comment) AS total_comments
from user_comment
where status = 0
group by 1) t ON t.image_id = p.id
这将返回所有帖子,对于没有评论(状态为0)的帖子,评论总数为零。
请参阅SQLFiddle
答案 8 :(得分:0)
SELECT
IFNULL(SUM(c.Total_Comment),0) AS comments,
post.Id
FROM
post p
JOIN user_comment c ON c.Image_Id = p.Id
AND c.Status=0
group by p.Id
答案 9 :(得分:0)
使用此查询..
SELECT COUNT(*) FROM user_comment INNER JOIN post ON user_comment.Image_Name = post.File_Name WHERE user_comment.Status = 0 AND user_comment.Image_Name = "your image id here";
查询工作正常,如果没有,那么只需改变从mysql获取数据/总评论的方式。