Get latest comments from multiple tables - php

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!
}
}
}

Related

Distinguishing ID's

This is my query:
$tsql = "SELECT *
FROM
dbo.messages m INNER JOIN
dbo.contacts c
ON m.contactID = c.ID
WHERE
assigned='{$_COOKIE['member_name']}'
ORDER BY
m.status DESC, m.ID DESC";
This returns the contact ID but not the message ID. How do I get it to show:
<?php echo $row['ID'] ?>
But with the message ID and not the contact ID in an HTML form?
you can access id of c table using cid, and id of m table as mid
like $row['cid'] and $row['mid']
$tsql = "SELECT m.*, c.*, c.id as cid, m.id as mid
FROM
dbo.messages m INNER JOIN
dbo.contacts c
ON m.contactID = c.ID
WHERE
assigned='{$_COOKIE['member_name']}'
ORDER BY
m.status DESC, m.ID DESC";

SELECT posts, its last 3 comments and count of all comments

SELECT posts, its last 3 comments and count of all comments
My code:
SELECT p.*, u.id, u.username username, u.usersurname usersurname, u.usermainphoto userphoto, GROUP_CONCAT(c.text SEPARATOR 'a!k#h#md%o^v&') commenttext,GROUP_CONCAT(c.likes SEPARATOR '-') commentlikes,GROUP_CONCAT(c.dislikes SEPARATOR '-') commentdislikes, GROUP_CONCAT(c.commentdate) commentdate, GROUP_CONCAT(u2.username) commentauthorname, GROUP_CONCAT(c.anonim) commentanonym, GROUP_CONCAT(c.id) commentid, GROUP_CONCAT(u2.id) commentauthorid, GROUP_CONCAT(u2.usersurname) commentauthorsurname, GROUP_CONCAT(u2.usermainphoto) commentauthorphoto, GROUP_CONCAT(c.commentphotoid) commentphotoid
FROM posts p
LEFT JOIN comments c ON c.post = p.postid AND c.commentdel=0
LEFT JOIN users u ON u.id = p.postauthorid
LEFT JOIN users u2 ON u2.id = c.author
WHERE p.postwallid = :id AND p.postdel=0
GROUP BY postid
ORDER BY postid DESC
it gives me all comments, but I need only 3
You need a timestamp or counter of something to determine which comments are the three you want. Add that column name between the angle brackets below.
SELECT p.*, u.id, u.username username, u.usersurname usersurname, u.usermainphoto userphoto, GROUP_CONCAT(c.text SEPARATOR 'a!k#h#md%o^v&') commenttext,GROUP_CONCAT(c.likes SEPARATOR '-') commentlikes,GROUP_CONCAT(c.dislikes SEPARATOR '-') commentdislikes, GROUP_CONCAT(c.commentdate) commentdate, GROUP_CONCAT(u2.username) commentauthorname, GROUP_CONCAT(c.anonim) commentanonym, GROUP_CONCAT(c.id) commentid, GROUP_CONCAT(u2.id) commentauthorid, GROUP_CONCAT(u2.usersurname) commentauthorsurname, GROUP_CONCAT(u2.usermainphoto) commentauthorphoto, GROUP_CONCAT(c.commentphotoid) commentphotoid
FROM posts p
LEFT JOIN comments c ON c.post = p.postid AND c.commentdel = 0
LEFT JOIN users u ON u.id = p.postauthorid
LEFT JOIN users u2 ON u2.id = c.author
WHERE p.postwallid = :id AND p.postdel = 0
and (
select count(*) from comments as c2
where c2.postid = p.postid and c2.commentdel = 0
and c2.<timestamp> <= c.timestamp
) < 3
GROUP BY postid
ORDER BY postid DESC
Edit: I didn't add the count of all comments. I think you can easily add it with another subquery in the select list but I know MySQL people don't like subqueries very much.
(
select count(*) from comments as c2
where c2.postid = c.postid and c2.commentdel = 0
) as comment_count
I add in SELECT count(postid) as all_comments and at the end LIMIT 0, 3
SELECT count(postid) as all_comments, p.*, u.id, u.username username, u.usersurname usersurname, u.usermainphoto userphoto, GROUP_CONCAT(c.text SEPARATOR 'a!k#h#md%o^v&') commenttext,GROUP_CONCAT(c.likes SEPARATOR '-') commentlikes,GROUP_CONCAT(c.dislikes SEPARATOR '-') commentdislikes, GROUP_CONCAT(c.commentdate) commentdate, GROUP_CONCAT(u2.username) commentauthorname, GROUP_CONCAT(c.anonim) commentanonym, GROUP_CONCAT(c.id) commentid, GROUP_CONCAT(u2.id) commentauthorid, GROUP_CONCAT(u2.usersurname) commentauthorsurname, GROUP_CONCAT(u2.usermainphoto) commentauthorphoto, GROUP_CONCAT(c.commentphotoid) commentphotoid
FROM posts p
LEFT JOIN comments c ON c.post = p.postid AND c.commentdel=0
LEFT JOIN users u ON u.id = p.postauthorid
LEFT JOIN users u2 ON u2.id = c.author
WHERE p.postwallid = :id AND p.postdel=0
GROUP BY postid
ORDER BY postid DESC
LIMIT 0, 3

7 query with inner join into 1 query, mysql

i have a question, how do i make totally 7 query into 1 query? to make the db query lesser? i have 1 table contain all of it, but the suggest is a "separator", each suggest i have to load 33 rows and order by dateline, i have think about use any inner join ... etc, but i think that is not a way? correct me if i'm wrong. Would Appreciate for help!THanks!!
This is the mysql query 1
$query = DB::query("SELECT t.*, d.did AS dingid, d.id AS dingpid, f.id AS bookmark, f.uid AS buid
FROM ".DB::table('comeing_tao')." AS t
LEFT JOIN ".DB::table('comeing_tao_ding')." AS d ON t.id = d.id AND d.uid = ".$_G['uid']."
LEFT JOIN ".DB::table('comeing_tao_fans')." AS f ON t.id = f.id AND f.uid = ".$_G['uid']."
WHERE t.suggest = 0 AND t.state = 1 ORDER BY dateline DESC LIMIT 33");
This is the mysql query 2
$query = DB::query("SELECT t.*, d.did AS dingid, d.id AS dingpid, f.id AS bookmark, f.uid AS buid
FROM ".DB::table('comeing_tao')." AS t
LEFT JOIN ".DB::table('comeing_tao_ding')." AS d ON t.id = d.id AND d.uid = ".$_G['uid']."
LEFT JOIN ".DB::table('comeing_tao_fans')." AS f ON t.id = f.id AND f.uid = ".$_G['uid']."
WHERE t.suggest = 1 AND t.state = 1 ORDER BY dateline DESC LIMIT 33");
This is the mysql query 3
$query = DB::query("SELECT t.*, d.did AS dingid, d.id AS dingpid, f.id AS bookmark, f.uid AS buid
FROM ".DB::table('comeing_tao')." AS t
LEFT JOIN ".DB::table('comeing_tao_ding')." AS d ON t.id = d.id AND d.uid = ".$_G['uid']."
LEFT JOIN ".DB::table('comeing_tao_fans')." AS f ON t.id = f.id AND f.uid = ".$_G['uid']."
WHERE t.suggest = 2 AND t.state = 1 ORDER BY dateline DESC LIMIT 33");
This is the mysql query 3
$query = DB::query("SELECT t.*, d.did AS dingid, d.id AS dingpid, f.id AS bookmark, f.uid AS buid
FROM ".DB::table('comeing_tao')." AS t
LEFT JOIN ".DB::table('comeing_tao_ding')." AS d ON t.id = d.id AND d.uid = ".$_G['uid']."
LEFT JOIN ".DB::table('comeing_tao_fans')." AS f ON t.id = f.id AND f.uid = ".$_G['uid']."
WHERE t.suggest = 3 AND t.state = 1 ORDER BY dateline DESC LIMIT 33");
This is the mysql query 4
$query = DB::query("SELECT t.*, d.did AS dingid, d.id AS dingpid, f.id AS bookmark, f.uid AS buid
FROM ".DB::table('comeing_tao')." AS t
LEFT JOIN ".DB::table('comeing_tao_ding')." AS d ON t.id = d.id AND d.uid = ".$_G['uid']."
LEFT JOIN ".DB::table('comeing_tao_fans')." AS f ON t.id = f.id AND f.uid = ".$_G['uid']."
WHERE t.suggest = 4 AND t.state = 1 ORDER BY dateline DESC LIMIT 33");
and so on... i skip the following 3 query cos is totally same except the t.suggest = 5, t.suggest = 6, t.suggest = 7
the goal is all the query in one, then play around with the array.
you can use OR
(t.suggest=3 OR t.suggest=4 OR ...) AND ...
if you want max 33 records from each suggest, try UNION
(SELECT ...) UNION (SELECT ...) UNION (SELECT ...) ...
TRY in clause
SELECT
t.*, d.did AS dingid, d.id AS dingpid, f.id AS bookmark, f.uid AS buid
FROM
".DB::table('comeing_tao')." AS t
LEFT JOIN ".DB::table('comeing_tao_ding')." AS d ON t.id = d.id AND d.uid =
".$_G['uid']."
LEFT JOIN ".DB::table('comeing_tao_fans')." AS f ON t.id = f.id AND f.uid =
".$_G['uid']."
WHERE
t.suggest IN(0,1,2,3,4,5,6,7)
AND
t.state = 1
ORDER BY
dateline DESC
but Limit will not give 33 records for each but 33 for whole return

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

Help with a joined query (MySQL)

Hello can anybody see why this query fails?
SELECT A.idAd, A.ads_in_Cat, A.title, A.currency, A.price,
A.in_dpt, A.description, A.featured FROM ads A
LEFT JOIN featured F ON F.ad = A.idAd
INNER JOIN dept D ON D.id_dept = A.in_dpt
INNER JOIN sub_cat_ad S ON S.id_sub_cat = A.ads_in_Cat
INNER JOIN cat_ad C ON C.idCat_ad = S.from_cat_ad
ORDER BY A.featured DESC LIMIT :limit, :offset
But this one works:
SELECT *FROM ads
LEFT JOIN featured ON featured.ad = ads.idAd
INNER JOIN dept ON dept.id_dept = ads.in_dpt
INNER JOIN sub_cat_ad ON id_sub_cat = ads.ads_in_Cat
INNER JOIN cat_ad ON idCat_ad = sub_cat_ad.from_cat_ad
ORDER BY featured DESC LIMIT :limit, :offset
In the first one, I don't want all columns from the table "ads", the query returns only columns till ...FROM ads A.
If you specify to only select fields from A that's what you get: Only fields from A.
If you want fields from other tables too you have to specify them as well.
SELECT
A.idAd, A.ads_in_Cat, A.title, A.currency, A.price, A.in_dpt, A.description, A.featured,
F.*,
D.*,
S.*,
C.*
FROM ads A
LEFT JOIN featured F ON F.ad = A.idAd
INNER JOIN dept D ON D.id_dept = A.in_dpt
INNER JOIN sub_cat_ad S ON S.id_sub_cat = A.ads_in_Cat
INNER JOIN cat_ad C ON C.idCat_ad = S.from_cat_ad
ORDER BY A.featured DESC LIMIT :limit, :offset

Categories