List comments by number of likes - php

I'm trying to get PHP to list out comments by descending number of likes they receive.
Currently, the comments' content and the number of likes they receive are in 2 separate tables: "comments" and "likes".
PHP code:
To get comments from "comments" table:
$this->db->order_by ('comment_id', 'asc');
$data['comment'] = $this->db->select()->get('comment');
To get likes from "likes" table:
$data['like'] = $this->db->get('like');
To show the number of likes for each comment:
$query_like=$this->db->query("select ip from like where comment_id='$comment_id'");
$count_like=$query_like->num_rows();
I'm wondering if it's possible to order the comments by the number of likes they receive without changing the tables' structure. Any advice hugely appreciated.

If I understand the data structure correctly, you just need a join and an aggregation:
select c.*, count(*) as numlikes
from comments c join
upvote l
on c.comment_id = l.comment_id
group by c.comment_id
order by count(*) desc;
EDIT:
To get comments with zero upvotes, do the left outer join in the other direction:
SELECT c.*, count(u.comment_id) as num_upvotes
FROM comment c left join
upvote u
on c.comment_id = u.comment_id
WHERE c.comment_id = '$interview_id'
GROUP BY c.comment_id
ORDER BY num_upvotes DESC;

Related

How can I get data from 3 tables?

I have 3 tables: 'news', 'comments' and 'rub'. I need to get all data from 'news', get 'title' from 'rub' and count the number of comments for every news.
Now I'm not able to get 'title' from 'rub'. The code below works:
SELECT n.id,n.header,n.text, COUNT(c.news_id) AS comments
FROM news n
LEFT JOIN comments c ON n.id = c.news_id
GROUP BY n.id
ORDER by n.id
LIMIT 30
But I need something like that and this code doesn't work (Call to a member function fetch_array() on a non-object):
SELECT n.id,n.header,n.text,r.title COUNT(c.news_id) AS comments
FROM news n,rub r
LEFT JOIN comments c ON n.id = c.new_id AND r.news_id=n.id
GROUP BY n.id ORDER by n.id
LIMIT 30
How to fix it?
It's not really clear to me what you are asking, but you need another JOIN. And you need to move the join condition for the rub table to that JOIN keyword, not into the join condition for the comments table
SELECT n.id,
n.header,
n.text,
r.title, -- comma was missing (as halfer mentioned)
COUNT(c.news_id) AS comments
FROM news n
JOIN rub r ON r.news_id=n.id --- this is missing
LEFT JOIN comments c ON n.id = c.new_id -- no join condition for rub/news here
GROUP BY n.id
ORDER by n.id
LIMIT 30
Your usage of the GROUP BY operator is also wrong. The above query will (rightfully) be rejected by all other DBMS.
Please read the following to understand why your GROUP BY is wrong:
http://www.mysqlperformanceblog.com/2006/09/06/wrong-group-by-makes-your-queries-fragile/
http://rpbouman.blogspot.de/2007/05/debunking-group-by-myths.html

How to get comments and replies?

I am trying to make a comments and replies to comments for media posted by users.
My comments table is structured like:
commentId : parentCommentId : mediaId : userId : comment
I want to select the most recent 10 original comments and their replies to a mediaId.
To do this I am running 2 sql statements.
SELECT commentId FROM comments
WHERE mediaId='3' AND parentCommentId='0'
LIMIT 10;
(This gets the commentIds of the most recent original 10 posts.
I then use these commentIds in the following)...
SELECT c.*,u.* FROM comments AS c
JOIN users AS u on u.userId=c.userId
WHERE parentCommentId IN --( *****commentIds from previous query***** );
Is there a better way to do this? Perhaphs using a JOIN?
What if you make it this way:
SELECT c.*,u.* FROM comments c
JOIN users u on u.userId=c.userId
JOIN comments p_c on p_c.commentId = c.parentCommentId
WHERE p_c.mediaId='3' AND p_c.parentCommentId='0'
LIMIT 10;
This will be useful for your problem
SELECT c.*,u.* FROM comments AS c
INNER JOIN users AS u on u.userId=c.userId
INNER JOIN comments pc on pc.commentId = c.CommentId
WHERE pc.mediaId='3' AND pc.parentCommentId='0'
LIMIT 10;

Codeigniter 2.1 - join two tables and count in the same query

I have two tables:
news ->
id_news
title
body
date_created
image
category_id
comments ->
id_comments
news_id
body
date_created
How can I write query to get all news, count all the comments for every news and present that query in the view part?
select
N.ID_News,
N.Title,
N.Body,
N.Date_Created,
N.Image,
N.Category_ID,
count(C.ID_Comments) CommentCount
from
News N
LEFT JOIN Comments C
on N.ID_News = C.News_ID
group by
N.ID_News
order by
whatever column(s) are important to you
Since we are counting, we need to make a minor change to DRap's Query:
select
N.ID_News,
N.Title,
N.Body,
N.Date_Created,
N.Image,
N.Category_ID,
count(C.ID_Comments) CommentCount
from
News N
LEFT JOIN Comments C
on N.ID_News = C.News_ID
order by
whatever column(s) are important to you
That will only give you only one result.. as that query lacks a group by statement, I would recommend changing that query to this:
select
N.ID_News,
N.Title,
N.Body,
N.Date_Created,
N.Image,
N.Category_ID,
count(C.ID_Comments) CommentCount
from
News N
LEFT JOIN Comments C
on N.ID_News = C.News_ID
group by
N.title
order by
whatever column(s) are important to you
Writing this down in the Active Record format stays something like this:
$this->db->select('N.ID_News, N.Title, N.Body, N.Date_Created, N.Image')
$this->db->select('N.Category_ID, count(C.ID_Comments) AS CommentCount');
$this->db->from('News AS N');
$this->db->join('commentas AS C', 'N.ID_News = C.News_ID', 'left');
$this->db->group_by('N.title');
After this you can use the order by funtion, to order the resultsas you seefit.

joining a count on a query

I have 2 tables: comments & blog
blog has the following fields: id(Unique key),title, author, body, date, img, imgdes, tags
comments : key(Unique key), postid(related to the id of blog),name, email, date, message
Im trying to display all of my blog post and the number of comments on every post.
So im trying to "count(postid) where postid=id"
I got something to work but its based around having 1 comment which wont work but this is it:
SELECT a.postid,c.author,c.title, c.id,c.body,c.date,c.pic, c.tags, c.imgdesc,
COUNT(*) AS num_comments FROM comments a LEFT JOIN blog c ON c.id = a.postid
GROUP BY c.id order by id DESC"
Again this only work when everything has a comment and i get why but i cant figure out how to implement what I want.
To put it all out there i have:
$sql="***( help 1 of 2) what to set the query to****"
$query = mysql_query($sql) or die(mysql_error());
<?php do{ ?>
<html stuff here>
<?php echo $blog['title']?><br>
<?php echo $blog['*******(help 2 of 2) # of comments display here******']
<?php } while($blog = mysql_fetch_assoc($sql));?>
im sure this is a easy join but i have no clue thanks!
Use this query it may works for you
SELECT a.postid,c.author,c.title, c.id,c.body,c.date,c.pic, c.tags, c.imgdesc, COUNT(a.key) AS num_comments FROM blog c left outer join comments a ON a.postid = c.id GROUP BY c.id order by id DESC
if you want all the blog posts then it should be on the left side of the left join.
I think the issue lies where you write: FROM comments a LEFT JOIN blog c ON c.id = a.postid
GROUP BY c.id order by id DESC"
The comments a and blog c don't seem to be correct references.
Should it be FROM comments.a LEFT JOIN blog.c ON ...?
Are you trying to count the number of comments in each blog? if yes then,
SELECT c.postid,count(key) as num_of_comments
FROM blog b, comments c
WHERE b.id = c.postid
GROUP BY c.postid
Another easy way out:
As you have the postid as a foreign key, you can just get the results from comments table
SELECT postid,count(key) as num_of_comments
FROM comments
GROUP BY postid

PHP & Mysql - Left Outer Join between two tables

I have two tables called 'events' and 'topics' each table can have many comments.
What I need to do is list all the events and topics with the amount of comments for each row. I've managed to return all the topics, which works great but I don't know how I can add the events table to the MySql. The comments and events table fields are listed below. Can anyone help me with this query?
Events:
ID
Event_Name
Comments:
post_id <-- the releated id for either the events or topics table
table <-- The table that the row belongs to so either topics or events
SELECT
t.id, t.title, c.created_at,
IF(ISNULL(c.allComments), 0, c.allComments) AS totalComments
FROM topics AS t
LEFT OUTER JOIN (
SELECT created_at, post_id, COUNT(*) AS allComments
FROM comments
GROUP BY post_id
) AS c ON c.post_id = t.id
ORDER BY tc.created_at DESC, c.allComments DESC
Sounds like events and topics should be the same table.
Still, I think we can do this with a UNION. Events and Topics have the same columns i hope? (Or at least the same important ones?)
(SELECT c.table as event_or_topic, e.*, count(C.table), MAX(C.created_at) as latest_c
FROM events E LEFT JOIN comments C on (C.post_id = E.id)
WHERE C.table = 'Events'
GROUP BY C.post_id)
UNION
(SELECT c.table as event_or_topic, t.id*, count(C.table), MAX(C.created_at) as latest_c
FROM topics T LEFT JOIN comments C on (C.post_id = E.id)
WHERE C.table = 'Topics'
GROUP BY C.post_id)
ORDER BY latest_c
Notice that the ORDER BY applies to the whole UNION, not the individual SELECTs.
The use of LEFT JOIN should allow those rows without Comments to still show. I think the problem is that we have parts of our select dependent on comments (ie - C.table, ordering on last comment, etc). The count should be fine - will just be zero if there are no comments.
You might need to change the SELECT part slightly. I'd like to display C.table so you know whether a row is a topic or event, but im afraid it might screw up the count. Do you need anything from comments besides the count? You use some columns other than post_id and table in your query that you neglected to explain in your question.
You still have columns I don't know what they are, like Comment's zoneTable
Try this:
SELECT
t.id, t.title, c.created_at, COUNT(c.allComments) AS totalComments
FROM topics AS t LEFT JOIN comments c ON t.id=c.post_id
GROUP BY t.id ORDER BY tc.created_at DESC, c.allComments DESC
If I understand your question you have 3 tables:
-Events
-Topics
-Comments
If that is true something like this should extract all the data:
SELECT *
FROM events,topics
LEFT JOIN comments ON post_ID = ID
ORDER BY date DESC
Hope i'm along the right lines!
W.
I've got it working. If anyone knows of a better and an efficient way of doing this, then please let me know:
(SELECT t.id, t.title, tc.dateCreated AS commentDate,
IF(ISNULL(tc.allComments), 0, tc.allComments) AS totalComments,
t.LastActive as dateChanged
FROM Events AS t
LEFT OUTER JOIN (
SELECT MAX(created_at) AS dateCreated, post_id,
COUNT(*) AS allComments
FROM comments
GROUP BY post_id
) AS tc ON tc.post_id = t.id)
UNION
(SELECT t.id, t.title, tc.dateCreated AS commentDate,
IF(ISNULL(tc.allComments), 0, tc.allComments) AS totalComments,
t.LastActive as dateChanged
FROM topics AS t
LEFT OUTER JOIN (
SELECT MAX(created_at) AS dateCreated, post_id,
COUNT(*) AS allComments
FROM comments
GROUP BY post_id
) AS tc ON tc.post_id = t.id)
ORDER BY commentDate DESC, dateChanged DESC, totalComments DESC

Categories