Reputation: 2732
I'm relatively new to MySQL and I am stumped with this section.
I am building a simple blog page which will display a blog along with the comments associated with it. I currently have two tables to handle this data:
Blogs
.blog_id (primary), .blog_title, .blog_date, .blog_post
Comments
.comment_id (primary), .blog_id, .comment_name, .comment
What I am trying to do is pull a specific blog which matches an ID and pull the comments tied to that blog. Here is my query:
SELECT * FROM blogs JOIN comments ON blogs.blog_id=comments.blog_id WHERE blogs.blog_id = $active ORDER BY comments.comment_id
This query results in pulling the correct information but if there are two comments on the blog, it will display the blog and everything twice as it's looping through the comments. I want to display all the blog information once and then have it loop through the comments.
I hope I explained this clearly. Any help would be fantastic. Thank you.
Upvotes: 2
Views: 4120
Reputation: 373
There are two section that you need to look into, one is your query and another is how you display the things.
I've just found some simple tool to build MYSQL query and analyse the you query, you can even connect your database with the website.
You can search in google chrome market or go via below link.
I'm just give a suggestion and direction rather than actually solve it.
Upvotes: 0
Reputation: 1665
There are two ways you could approach this:
If you absolutely need to do this in one query, use your joined SQL and iterate over the results using the blog's ID as a unique key:
$blogId = 0;
while ( null != ($row = mysql_fetch_assoc( $result ) ) )
{
if ( $row['blog_id'] != $blogId )
{
// Display blog contents here
$blogId = $row['blog_id'];
}
// Print coment
}
The more efficient way is to run this as two queries. First Select the Blog information, with a count of POSTS:
SELECT blog_id, blog_title, blog_date, blog_post, COUNT(*) as comment_count
FROM blogs INNER JOIN comments ON blogs.blog_id = comments.blog_id
WHERE blog_id = $blogId
GROUP BY blog_id, blog_title, blog_date, blog_post;
or, using a sub-select:
SELECT blog_id, blog_title, blog_date,
(SELECT COUNT(*) FROM comments WHERE blog_id = blog.blog_id) as comment_count
FROM blogs
WHERE blog_id = $blogId
Not to mention there are different kinds of blog views; on an index page, the second query would be all you need to pull the blog summary and a count of comments on each post, without needing to display the contents of each comment.
Upvotes: 0
Reputation: 66122
The behavior you are describing is what a join is supposed to do. If you only want 1 record for each of the blog entries, then you need to use group by. To get a list of all the blogs records with the number of comments you can do a query like:
SELECT blogs.*,Count(comments.comment_ID)
FROM blogs
LEFT JOIN comments
ON blogs.blog_id=comments.blog_id WHERE blogs.blog_id = $active
ORDER BY comments.comment_id
GROUP By Blog.BlogID
However, you said you wanted to display just the blog, and then the comments associated with that blog. In that case you would most likely just use an initial query to pull all the blogs, and then another query as you loop through all the blog entries to get the comments for each blog. Here is some pseudocode.
select * FROM blogs
For each record from above
Code for displaying blog goes here
Select * FROM Comments where Blog_id = $blogID
For each comment from above query
code for displaying comment goes here
Next COmment
Next Blog
You could just do a single select for all the comments, which would be more efficient, but makes the resulting code more complex as you have to find the records using php in the resulting list. It's mush simpler to just use multiple queries, and for most blogs (10 articles on a page, max) it won't make much of a difference. If you really want to use a single query, you can structure your program as in the pseudocode below.
SELECT * FROM blogs
LEFT JOIN comments ON blogs.blog_id=comments.blog_id
WHERE blogs.blog_id = $active ORDER BY blogs.blog_id, comments.comment_id
$LastBlogID = -1
FOR EACH Record
If $LastBlogID != record['blog_id']
Display Blog Information
$LastBlogID = record['blog_id']
End If
Display Comment Information
Next Record
Upvotes: 3