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.

My message table

enter image description here

My comments table

enter image description here

The result looks like this: enter image description here

OR

enter image description here

But I want how

enter image description here

OR enter image description here

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 &nbsp;<?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';?>

      

+3


source to share


10 replies


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.

0


source


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.

+2


source


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

      

I believe that group by

s inner join

should help you get what you want. Hope this helps.

+1


source


you need left join

andgroup by

This will return null comments for posts that have no table entries 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

      

0


source


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

      

0


source


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

      

0


source


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.

0


source


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

      

0


source


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

0


source


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

      

0


source







All Articles