Count one table and ORDER BY it - php

I want to order my blog posts by the amount of comments. To retrieve my posts etc i use:
$result = DB::query("SELECT R.rumorID, R.rumor_author, R.rumor_title, R.rumor_text, T.topic_name, A.first_name, A.surname, T.topicID, R.datum_geplaatst
FROM Rumor R JOIN Account A
ON A.userID = R.rumor_author
JOIN Topic T
ON T.topicID = R.topicID
ORDER BY $sortby $order");
foreach ($result as $rumor) {
$r_id = $rumor['rumorID'];
The $sortby and $order is a $_GET, i use links to "order by" the blog.
To retrieve the number of comments that comes with a blog post, i use:
$commentcount = DB::query("SELECT count(*)
FROM Rumor R JOIN Comment C
ON R.rumorID = C.rumorID
WHERE R.rumorID = :rumor", array(':rumor' => $r_id));
$rumortext = $rumor['rumor_text'];
$date = $rumor['datum_geplaatst'];
$countcomments = $commentcount[0]['count(*)'];
So, I can order by Date,title, topic, author etc. But how do i manage to order by the amount of comments?

This could be way off. Writing from the top of my head here:
SELECT R.rumorID, R.rumor_author, R.rumor_title, R.rumor_text, T.topic_name, A.first_name, A.surname, T.topicID, R.datum_geplaatst, count(c.rumorID) AS commentCount
FROM Rumor R
JOIN Account A ON A.userID = R.rumor_author
JOIN Topic T ON T.topicID = R.topicID
LEFT JOIN Comment C ON R.rumorID = C.rumorID
GROUP BY R.rumorID
ORDER BY commentCount ASC

Related

Fetch very last recent single comments on each post

Fetch very last recent single comments on each post
SELECT *
FROM ( `comments` )
LEFT JOIN `posts`
ON `posts`.`id` = `comments`.`case_id`
WHERE `comments`.`user_id` = '8'
GROUP BY `comments`.`case_id`
ORDER BY `comments`.`created_date` DESC
Try this and let me know if it responds to your question:
SELECT * FROM comments
RIGHT JOIN posts ON posts.id = comments.case_id
WHERE comments.user_id = '8' AND comments.created_date = (SELECT MAX(created_date) FROM comments WHERE case_id = posts.id)
Why not getting the list of post IDs belonging to that user:
SELECT posts.id
FROM posts
INNER JOIN comments ON posts.id = comments.case_id
WHERE comments.user_id = 8
Then foreach($IDs as $id):
SELECT * FROM comments
WHERE case_id = ${id}
ORDER BY created_date DESC
LIMIT 1
Original answer:
You are just missing the LIMIT clause:
SELECT * from comments
LEFT JOIN posts ON posts.id = comments.case_id
WHERE comments.user_id = 8
GROUP BY comments.case_id
ORDER BY comments.created_date DESC
LIMIT 1
SELECT
*
FROM
posts
LEFT JOIN comments ON comments.case_id = posts.post_id
WHERE
comments.comments_id IN (
SELECT
MAX(comments_id)
FROM
comments
GROUP BY
case_id
)
AND comments.user_id = '8'
Hope it helps

Get latest comments from multiple tables

I'm having trouble with getting the 3 latest comments from two different tables.
Here is my code, which works perfect with one inner join:
$query = mysql_query("SELECT COUNT(c.topic_id) AS ctid, COUNT(c.deck_id) AS dtid, f.id AS forumid, f.class AS forumclass, f.name AS forumname, f.url AS forumurl,
c.id AS commentid, c.user_id AS commentuser, c.user_name AS commentusername, c.date AS commentdate,
c.topic_id AS topicid, c.deck_id AS deckid
FROM ".$prefix."comment AS c
INNER JOIN ".$prefix."forum AS f
ON c.topic_id = f.id GROUP BY f.id
ORDER BY commentdate DESC LIMIT 3") or die(mysql_error());
This works fine it shows the 3 latest comments from the forum table, however I have comments in the decks table too, but when I add another JOIN to the query it just won't work anymore.
$query = mysql_query("SELECT COUNT(c.topic_id) AS ctid, COUNT(c.deck_id) AS dtid, f.id AS forumid, f.class AS forumclass, f.name AS forumname, f.url AS forumurl,
c.id AS commentid, c.user_id AS commentuser, c.user_name AS commentusername, c.date AS commentdate,
c.topic_id AS topicid, c.deck_id AS deckid, , d.id, d.url AS deckurl, d.name AS deckname
FROM ".$prefix."comment AS c
INNER JOIN ".$prefix."forum AS f
ON c.topic_id = f.id
INNER JOIN ".$prefix."decks AS d
ON c.deck_id = d.id
GROUP BY f.id ORDER BY commentdate DESC LIMIT 3") or die(mysql_error());
There's a comment table and in the comment table there is a topic_id column, which is equal to the forum table's id column and there's also a deck_id column which is equal to the decks table's id column.
Obviously that GROUP BY f.id isn't good with the two inner joins.
After this query I have while ($top = mysql_fetch_assoc($query)){ ... and then if ($top['deckid']==0) then print the topicid informations else print the deckid informations.
EDIT:
Comment table (only what is important to us now):
id, topic_id, deck_id
topic_id = forum table's id
deck_id = deck table's id
Obviously there is no comment to every forum topic.
E.g.: Forum ID 5 has 4 comments, then comment table e.g.: ID 1,2,3,4 has topic_id 4,4,4,4 and deck_id 0,0,0,0.
If there's no comment then there's nothing in the comment table. So forum ID 6 has 0 comments, then there is nothing in the comments table.
If deck ID 12 has 2 comments, then comment table e.g.: 5,6 has deck_id 12,12 and topic_id 0,0.
Forum table:
id
Deck table:
id
EDIT2: Solution (not too nice, but it works):
//count how many comments the latest 3 deck topic has
$new_comment_query = mysql_query("SELECT COUNT(c.deck_id) AS dtid, c.id, c.deck_id, c.date, d.id
FROM ".$prefix."comment AS c LEFT JOIN ".$prefix."decks AS d ON d.id = c.deck_id GROUP BY d.id ORDER BY date DESC LIMIT 3");
$new_one = mysql_fetch_array($new_comment_query);
//count how many comments the latest 3 forum topic has
$new_forum_query = mysql_query("SELECT COUNT(c.topic_id) AS ctid, c.id, c.topic_id, c.date, f.id
FROM ".$prefix."comment AS c LEFT JOIN ".$prefix."forum AS f ON f.id = c.topic_id GROUP BY f.id ORDER BY date DESC LIMIT 3");
$newer_one = mysql_fetch_array($new_forum_query);
//get all the comments
$comment_query = mysql_query("SELECT id, topic_id, deck_id, date FROM ".$prefix."comment ORDER BY date DESC LIMIT 3");
while ($comment = mysql_fetch_assoc($comment_query))
{
if($comment['topic_id']==0)
{
$deck_query = mysql_query("SELECT * FROM ".$prefix."decks WHERE id=".$comment['deck_id']);
while ($deck_comments = mysql_fetch_assoc($deck_query))
{
//print all the things!
}
}
elseif($comment['deck_id']==0)
{
$forum_query = mysql_query("SELECT * FROM ".$prefix."forum WHERE id=".$comment['topic_id']);
while ($forum_comments = mysql_fetch_assoc($forum_query))
{
//print all the things!
}
}
}
Try running this query:
SELECT * FROM
(
SELECT COUNT(c.topic_id) AS ctid, COUNT(c.deck_id) AS dtid,
f.id AS forumid, f.class AS forumclass, f.name AS forumname,
f.url AS forumurl,
c.id AS commentid, c.user_id AS commentuser, c.user_name AS commentusername,
c.date AS commentdate, c.topic_id AS topicid, c.deck_id AS deckid,
d.id, d.url AS deckurl, d.name AS deckname
FROM ".$prefix."comment AS c
INNER JOIN ".$prefix."forum AS f
ON c.topic_id = f.id
INNER JOIN ".$prefix."decks AS d
ON c.deck_id = d.id
ORDER BY commentdate DESC
) t1
GROUP BY t1.forumid
LIMIT 3
I first execute your complex JOIN without the GROUP BY which was causing problems. Then I SELECT everything from that temporary table, grouping by the forumid.
In all honesty, I'm surprised your server wasn't barfing on your first query, let alone the second, but hopefully my answer will help you out.
//count how many comments the latest 3 deck topic has
$new_comment_query = mysql_query("SELECT COUNT(c.deck_id) AS dtid, c.id, c.deck_id, c.date, d.id
FROM ".$prefix."comment AS c LEFT JOIN ".$prefix."decks AS d ON d.id = c.deck_id GROUP BY d.id ORDER BY date DESC LIMIT 3");
$new_one = mysql_fetch_array($new_comment_query);
//count how many comments the latest 3 forum topic has
$new_forum_query = mysql_query("SELECT COUNT(c.topic_id) AS ctid, c.id, c.topic_id, c.date, f.id
FROM ".$prefix."comment AS c LEFT JOIN ".$prefix."forum AS f ON f.id = c.topic_id GROUP BY f.id ORDER BY date DESC LIMIT 3");
$newer_one = mysql_fetch_array($new_forum_query);
//get all the comments
$comment_query = mysql_query("SELECT id, topic_id, deck_id, date FROM ".$prefix."comment ORDER BY date DESC LIMIT 3");
while ($comment = mysql_fetch_assoc($comment_query))
{
if($comment['topic_id']==0)
{
$deck_query = mysql_query("SELECT * FROM ".$prefix."decks WHERE id=".$comment['deck_id']);
while ($deck_comments = mysql_fetch_assoc($deck_query))
{
//print all the things!
}
}
elseif($comment['deck_id']==0)
{
$forum_query = mysql_query("SELECT * FROM ".$prefix."forum WHERE id=".$comment['topic_id']);
while ($forum_comments = mysql_fetch_assoc($forum_query))
{
//print all the things!
}
}
}

Combining 2 queries into 1

I'm looking to optimize two queries into one, if possible.
My first query searches for all the authors of a lyrics... Then, for each author found, i want to find the total numbers of lyrics the author was involded in...
Right now, im executing the first query and for each row found, i'm launching another query to get the authors total lyrics he was involved... So, if there is 4 authors i will end up launching 4 more queries...
That is to many queries in my opinion. That is why i've decided to write here, so i can get help on how to optimize my query...
This is the query i'm executing to get the author(s) responsable for a lyrics:
$sql = "SELECT author.author_id, author.name
FROM track INNER JOIN lyrics_author ON track.lyrics_id = lyrics_author.lyrics_id
INNER JOIN author ON lyrics_author.author_id = author.author_id
WHERE track.track_id = $trackid ";
This is the query to get the total number of lyrics the author as writing:
$total = "SELECT lyrics_author.author_id, count(*) as total
FROM lyrics_author
WHERE lyrics_author.author_id = $author_id
GROUP BY lyrics_author.author_id";
This is a sample of the code:
<?php
$trackid = 5;
$sql = "SELECT author.author_id, author.name
FROM track INNER JOIN lyrics_author ON track.lyrics_id = lyrics_author.lyrics_id
INNER JOIN author ON lyrics_author.author_id = author.author_id
WHERE track.track_id = $trackid ";
$result_author = # $conn->query($sql);
while ($row_author = $result_author->fetch_assoc()) {
$author_id = $row_author['author_id'];
$total = "SELECT lyrics_author.author_id, count(*) as total
FROM lyrics_author
WHERE lyrics_author.author_id = $author_id
GROUP BY lyrics_author.author_id";
$result_total_lyrics = # $conn->query($total);
$t = $result_total_lyrics->fetch_assoc();
echo $t['total'];
$result_total_lyrics->free();
}
$result_author->free();
?>
Is it posible to optimize this query? If yes, how? Is there a link you could refer, so i can learn...
Thanks
Marco
SELECT
author.author_id,
author.name,
COUNT(DISTINCT more_tracks.lyrics_id) AS total
FROM track
INNER JOIN lyrics_author USING (lyrics_id)
INNER JOIN author USING (author_id)
LEFT JOIN lyrics_author AS more_tracks USING (author_id)
WHERE track.track_id = $trackid
GROUP BY author.author_id
That's confusing as heck. Why are you passing in a trackid as a lyricsid when you have a property called lyricsid??
Anyway
Select author.author_id, author.name, Count(*)
inner join
(SELECT lyrics_author.author_id
FROM lyrics_author
INNER JOIN tracks ON track.lyrics_id = lyrics_author.lyrics_id
WHERE track.track_id = $lyricsid";
) as lyricalauthors
inner join lyrics_author on lyrics_author.author_id = lyricalauthors.author_id
On author.author_id = lyricalauthors.author_id
Group By Author.author_id,author.name
I think ...

Count number of comments in articles

Please I want to add another table (Comments) to this query to count the number of comments for each article.
$query = "SELECT M.id,M.j_surname,A.j_user_id,A.id,A.jart_title, A.jart_description, A.jart_createddate, COUNT(C.artid) AS count_comments FROM jt_articles A, jt_members M, jt_article_comments C where M.id = A.j_user_id AND C.artid = A.id ORDER BY A.jart_createddate DESC
update:
something like that (you dont post the scheme of the comments table)
SELECT M.id,M.j_surname,A.j_user_id,A.id,A.jart_title, A.jart_description,
A.jart_createddate , COUNT(A.id) AS count_comments
FROM jt_articles A
left join jt_members M on M.id = A.j_user_id
left join jt_article_comments C on C.artid = A.id
group by A.id
ORDER BY A.jart_createddate DESC

Ordering by posts in another table

I have created a feature where users can start new topics (similar to forums).
At the moment on a page, the query for the topics are as follows:
$q = "SELECT ".TBL_COMMUNITYTHREADS.".title, ".TBL_COMMUNITYTHREADS.".id,
".TBL_COMMUNITYTHREADS.".date, ".TBL_COMMUNITYTHREADS.".author, ".TBL_USERS.".username FROM ".TBL_COMMUNITYTHREADS."
INNER JOIN ".TBL_USERS." ON ".TBL_COMMUNITYTHREADS.".author = ".TBL_USERS.".id
WHERE type = '$type'
ORDER BY date DESC LIMIT $offset, $rowsperpage ";
The tables are constants and the offset and rowsperpage are variables passed in to limit how many posts are on a page.
At the moment though, all the topics are ordered by the date.
I want them to be ordered by the latest response.
Similarly to forums, when the reponse inside the topic is newest, that topic will go to the top.
The topics are stored in tbl_communitythreads and the replies in tbl_communityreplies.
How can I ordered them by the latest repsonse.
They are linked by the threadid in tbl_communityreplies. Also in that one is the date column.
Thankyou for reading, I just cant think of how to do this.
This:
SELECT c.title, c.id, c.date, c.author, u.username,
(
SELECT MAX(reply_date)
FROM tbl_communityreplies cr
WHERE cr.thread = c.id
) AS last_reply
FROM TBL_COMMUNITYTHREADS c
JOIN TBL_USERS u
ON u.id = c.author
ORDER BY
last_reply DESC, c.id DESC
LIMIT $offset, $rowsperpage
or this:
SELECT c.title, c.id, c.date, c.author, u.username
FROM (
SELECT cr.thread, cr.reply_date, cr.id
FROM tbl_communityreplies cr
WHERE (cr.last_reply, cr.id) =
(
SELECT last_reply, id
FROM tbl_communityreplies cri
WHERE cri.thread = cr.thread
ORDER BY
thread DESC, last_reply DESC, id DESC
)
ORDER BY
last_reply DESC, id DESC
LIMIT $offset, $rowsperpage
) q
JOIN TBL_COMMUNITYTHREADS c
ON c.id = q.thread
JOIN TBL_USERS u
ON u.id = c.author
ORDER BY
q.reply_date DESC, q.id DESC
The former query is more efficient for large values of $offset, or if you have few threads with lots of replies.
Issue the following commands:
CREATE INDEX ix_communitythreads_replydate_id ON TBL_COMMUNITYTHREADS (reply_date, id)
CREATE INDEX ix_communitythreads_thread_replydate_id ON TBL_COMMUNITYTHREADS (thread, reply_date, id)
for this to work fast.
by join with another table , then you can order by column from this table.

Categories