Select query in MySQL
I want to select the general comments posted in the post. Somehow I can do it, but the problem is that the general comment will be displayed under every post even if there are no comments.
Problem: Unable to get the comment associated with the post.
What I want:
To select a general comment associated with each post.
What I am trying:
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
Both queries return all (summary) comments for all posts, but I only want to show the comment associated with a particular post.
The result looks like this:
OR
But I want how
OR
UPDATE:
I think most people don't understand what I am trying to ask? so I am posting the index.php code where I access data from the database using a while loop and in the index.php page I want to access the general comment posted on a specific post.
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';?>
Update 2
I know the reason why the query is showing 2 or 3 under each post and the reason is because the query is picking the first or second id from the table and counting / summing it, but I cannot solve the problem because I want the sum of the comment for each post, not one comment ID for the whole post.
Note:
When I run the request on the page after the description, it works fine, but I want to show the total number of comments for each post in the index.php page ...
My post-description.php code
<?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';?>
Use this query ..
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";
The query works fine, if not for you, just change your way to get data / general comment from mysql.
If you run a separate request for each message sent, which is similar to what you are trying to do, we are just guessing based on the two messages you requested that return a single string ...
To use this pattern, you need to add an additional predicate to the clause WHERE
to determine which post
comment count you want to return. For example:
SELECT SUM(c.total_comment) AS comment
FROM user_comment c
WHERE c.status = 0
AND c.image_id = 2
If image_id
there are no rows for the given , the aggregate SUM()
will return NULL. You can handle this in your code and convert it to zero, or you can handle this in SQL so that it returns zero and not NULL. You can use a convenient function IFULL()
...
SELECT IFNULL(SUM(c.total_comment),0) AS comment
FROM user_comment c
WHERE c.status = 0
AND c.image_id = 2
If the first argument of the IFNULL function is NULL, the function returns the second argument, otherwise it returns the first.
IFNULL(a,b)
is short for MySQL for ANSI
CASE WHEN a IS NULL THEN b ELSE a END
This answers the question you asked. How to get an invoice for a specific job.
The other answers here address the issue with this approach ... running a separate request for each post is NOT the most efficient or most scalable design.
Each query requires feedback from the database, the database needs to parse the SQL text, validate the syntax, perform semantic validation, look up dictionaries to make sure the identifiers are valid, the database user has the necessary privileges, decide on the execution plan, and then run the query, prepare the result set and return to the caller. And this superstructure folds in a narrow loop.
Some other answers are addressed here. Instead of running a separate query for each image_id
, they get the count in one fell swoop. They do this by adding a column image_id
to the SELECT list and adding GROUP BY image_id
... to the query to return a result like this
image_id comment
-------- -------
2 3
5 2
This will return all non-zero values ββto you. BUT ... you don't run this in a loop that fetches rows from a columnar table ... you must first run this query and store the results in an array, and then for each post you paginate, you can find the array to find counter. If it is not found, then the count is zero.
You can also return null values ββand store them just like a query:
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
But that would be extra strings with zero, still searching for an array, the only difference is that you find a match ... really nothing else.
BUT ... you really don't want to do this at all.
What the query is really hinting at is the idea that you don't need a SEPRATE query to get the comment count; you can get this in ONE QUALITY that returns strings from post
.
Just add an outer join to the table user_comment
, add a clause GROUP BY
to the unique identifier in the table, post
and return that SUM () aggregate expression to the SELECT list along with the columns you rotate from the table post
. For example:
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
This is usually a much more scalable design to return results in a single query, rather than launching a boat with separate queries.
Alternatively, usually not as efficient as outer join, you should use a correlated subquery in the SELECT list:
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
Or we could also use the outer join operation for the inline view (but this is more applicable in the more general case when there are more joins involved and we don't want to double or triple the count, although this returns the same result in this case (assuming that id
is unique in the table 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
Followup
Based on the PHP code you posted, point ... you only need the SQL SINGLE statement .
Just return the resulting "total_comment" value for each post along with each post line, just change the query (as I pointed out in my answer above, there are several possible ways to get this result. Just tell the database to return this post (And for a more deterministic result, add a sentence ORDER BY
to the query.)
For example:
$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;
This is a very basic example that just displays the return values ββwithout all the HTML you really want to output. It serves to demonstrate that you do not need to run your code with a second or third SQL statement.
And (obviously) this example does not cover escaping potential HTML characters stored in database columns, nor does it handle PDO error handling, either setAttribute(PDO::ATTR_ERRORMODE,PDO::ERRMODE_EXCEPTION)
, and the corresponding try / catch / finally blocks, or adding separate return checks from calls prepare
and execute
. They are omitted to avoid pattern obfuscation.
source to share
If I understand correctly, you want a result like this ah?
Post
totalCommand
Post
totalCommand
Query:
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
source to share
It looks like based on the other comments, you forgot to include that original query after a certain number of user comments. Try adding User_Name
to WHERE CLAUSE
, assuming the variable is @username
somewhere in your code that you don't include:
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
source to share
Here is a SQLFiddle example with some dummy data.
But such a query will give you the total number of comments for one post.
SELECT COUNT(*) FROM comments INNER JOIN posts ON comments.`Image_Name` = posts.`File_Name` WHERE comments.status = 0 AND comments.Image_Name = "956.jpg";
Or, if you want to get the total number of comments for each post, you run a query like this:
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;
You can use COUNT()
instead SUM()
and you won't need the column anymore Total_Comment
. As a suggestion, I would suggest using a better relationship between tables (use IDs). And obviously change "956.jpg" to the filename you want to check, or change the columns you want to check.
source to share
I don't quite understand the purpose of having a "Total_comment" in the comment table where it can be easily achieved using "COUNT ()". For simplicity, I would use COUNT () in my example.
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
source to share
This works for me:
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
This returns all posts with zero comment sums for those non-comment posts (status 0).
See SQLFiddle
source to share