Jump to content

Order by over two tables?


gausie

Recommended Posts

Hi all

 

I have one table with a list of articles, and another with comments having an "article_id" to relate to which article they are about.

 

How can I take the list of articles in order of how many comments there are? i.e. one with most comments comes out first etc.

 

gausie

Link to comment
Share on other sites

Remember, it doesn't matter that you're gathering data from two tables.  You can ORDER BY any column in the result row.  To find the number of comments, you'll need to use GROUP BY to group the articles and count the comments relating to them.  Unfortunately, if you want the comments as well, the grouping will collapse them, so you'll need to do this with a subquery (4.1+) or two separate queries.

 


# To simply find articles in order of comments:
SELECT articles.article_id,title,COUNT(comment) AS num_comments
FROM articles LEFT JOIN comments ON articles.article_id=comments.article_id
GROUP BY articles.article_id
ORDER BY num_comments;

# To select the comments as well:
SELECT articles.article_id,title,comment.timestamp, comment
FROM articles LEFT JOIN comments ON articles.article_id=comments.article_id
LEFT JOIN (SELECT article_id,COUNT(comment) AS count FROM comments GROUP BY count) AS cc ON articles.article_id=cc.article_id
ORDER BY cc.count, comments.timestamp;

Link to comment
Share on other sites

That's "mak" (the articles table) ->

 

FieldTypeCollationNullExtra

idint(250)[/td]Noauto_increment

namevarchar(250)latin1_swedish_ciNo

infolongtextlatin1_swedish_ciNo

typevarchar(250)latin1_swedish_ciNo

uservarchar(250)latin1_swedish_ciNo

ratingint(250)No

votesint(250)No

dateint(250)No

 

 

That's "comments" ->

 

FieldTypeCollationNullExtra

idint(250)Noauto_increment

commentlongtextlatin1_swedish_ciNo

mak_idint(250)No

uservarchar(250)latin1_swedish_ciNo

dateint(11)No[td]

 

Hope that's enough information!

(and date means timestamp :P)

 

gausie

Link to comment
Share on other sites

So, using your table and column names, the first query I posted becomes:

 

SELECT mak.id,mak.name,COUNT(comments.comment) AS num_comments
FROM mak LEFT JOIN comments ON mak.id=comments.mak_id
GROUP BY mak.id
ORDER BY num_comments;

 

And the second...

 

SELECT mak.id,title,comments.date, comments.comment
FROM mak LEFT JOIN comments ON mak.id=comments.mak_id
LEFT JOIN (SELECT mak_id,COUNT(comment) AS count FROM comments GROUP BY count) AS cc ON mak.id=cc.mak_id
ORDER BY cc.count, comments.date;

Link to comment
Share on other sites

Typo; should have been mak_id.

 

SELECT mak.id,title,comments.date, comments.comment
FROM mak LEFT JOIN comments ON mak.id=comments.mak_id
LEFT JOIN (SELECT mak_id,COUNT(comment) AS num_comments FROM comments GROUP BY mak_id) AS cc ON mak.id=cc.mak_id
ORDER BY cc.num_comments, comments.date;

Link to comment
Share on other sites

That works - excellent!

 

One last question:

 

SELECT mak.id,name,mak.user,comments.date,comments.user,num_comments

FROM mak LEFT JOIN comments ON mak.id=comments.mak_id

LEFT JOIN (SELECT mak_id,COUNT(comment) AS num_comments FROM comments GROUP BY about)AS cc ON mak.id=cc.mak_id

ORDER BY comments.date;

 

How can I make it only return one (the most recent) comment?

 

gausie

 

 

Link to comment
Share on other sites

SELECT comment FROM comments ORDER BY date LIMIT 1;

 

(You can add more columns in the SELECT... part.)

 

You can return the article as well using a JOIN.

 

SELECT name,comment,comments.date
FROM mak JOIN comments ON mak.id=comments.mak_id
ORDER BY comments.date
LIMIT 1;

Link to comment
Share on other sites

I tried to do this myself but no luck -

 

I want to select each article, ordered by the most recent comment, and I want to return information about that most recent comment for each article. How do I do that?

 

gausie

Link to comment
Share on other sites

SELECT mak.id, mak.name, comments.date, comments.comment FROM mak JOIN comments ON mak.id=comments.mak_id JOIN (SELECT mak_id, MAX(id) AS latest FROM comments GROUP BY mak_id ORDER BY latest DESC) AS c2 ON comments.id=c2.latest ORDER BY comments.date DESC

 

That should work to get you the article and latest comment sorted by most recent as long as the assumption holds that the higher comment.id directly corresponds to a more recent comment.  You can add a LIMIT in the subquery if you want.  I also assumed you wouldn't want repeated articles.

Link to comment
Share on other sites

Wait no :-(

 

I tried to add a WHERE clause to picking from the mak table. I want sometimes to select only the articles with the "type" column having then value "item".

 

I tried adding a WHERE mak.type = "item", but I got an error in MySQL syntax

 

SELECT mak.id, mak.name, mak.user AS poster, mak.type, mak.rating, mak.votes, comments.date, c2.amount, comments.user

FROM mak

JOIN comments ON mak.id = comments.about

JOIN (

 

SELECT about, MAX( id ) AS latest, COUNT( * ) AS amount

FROM comments

GROUP BY about

ORDER BY latest DESC

) AS c2 ON comments.id = c2.latest

GROUP BY mak.id

WHERE mak.type = 'item'

ORDER BY comments.date DESC

 

Laasst piece of help?

Link to comment
Share on other sites

SELECT mak.id, mak.name, mak.type, mak.user AS poster, mak.rating, mak.votes, comments.date, c2.amount, comments.user FROM mak

JOIN comments ON mak.id = comments.about

 

JOIN (

SELECT about, MAX( id ) AS latest, COUNT(*) AS amount

FROM comments

WHERE comment NOT LIKE '<i>%</i>%'

GROUP BY about

ORDER BY latest DESC )

 

AS c2 ON comments.id = c2.latest

GROUP BY mak.id

ORDER BY comments.date DESC;

 

How can I make it discout the "WHERE comment NOT LIKE '<i>%</i>%' " if the amount of comments for this article is equal to 1?

 

gausie

Link to comment
Share on other sites

SELECT mak.id, mak.name, mak.type, mak.user AS poster, mak.rating, mak.votes, comments.date, c2.amount, comments.user FROM mak
JOIN comments ON mak.id = comments.about

JOIN (
SELECT about, MAX( id ) AS latest, COUNT(*) AS amount
FROM comments
WHERE comment NOT LIKE '\%%'
GROUP BY about HAVING amount>1
ORDER BY latest DESC )

AS c2 ON comments.id = c2.latest
GROUP BY mak.id
ORDER BY comments.date DESC;

if we don't use ' \' it won't return any records

Link to comment
Share on other sites

This thread is more than a year old. Please don't revive it unless you have something important to add.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.