質問

I have the following database schema

posts(id_post, post_content, creation_date)
comments(id_comment, id_post, comment_content, creation_date)

What i want to accomplish is query all posts sorted by most recent activity date, which basically means the first post fetched will be the latest post added OR the one with the latest comment added.

Hence, my first thought was something like

Select * From posts P, comments C
WHERE P.id_post=c.id_post
GROUP BY P.id_post
ORDER BY C.creation_date

The problem is the following: if a post doesn't have a comment it won't be fetched, because P.id_post=C.id_post won't match.

Basically, the idea is the following: I order by creation_date. If there are comments, creation_date will be the comment's creation date, elsewhere it will be the post's creation date.

Any help?

役に立ちましたか?

解決

Start by using proper join syntax. Then return appropriate columns. You are aggregating by id_post so there is only one row for each post. Putting an arbitrary comment on the same row would not (in general) be a sensible thing to do.

The answer to your question, though, is to order by the greatest of the two dates. The two dates are p.creation_date and `max(c.creation_date).

select P.*, max(P.creation_date)
From posts P left join
     comments C
     on P.id_post=c.id_post
group by P.id_post
order by greatest(p.creation_date, coalesce(max(c.creation_date), P.post_date));

The coalesce() is necessary because of the left outer join; the comment creation date could be NULL.

EDIT:

If you assume that comments come after posts, you can simplify the order by to:

order by coalesce(max(c.creation_date), P.post_date);

他のヒント

Use LEFT JOIN

Select * 
,(CASE WHEN C.creation_date IS NULL  THEN P.creation_date ELSE C.creation_date END) new_creation_date
From posts P
LEFT JOIN comments C ON (P.id_post=c.id_post)
GROUP BY P.id_post
ORDER BY new_creation_date DESC

or

Select * 
From posts P
LEFT JOIN comments C ON (P.id_post=c.id_post)
GROUP BY P.id_post
ORDER BY 
CASE WHEN C.creation_date IS NULL THEN P.creation_date ELSE C.creation_date END
DESC

Join tables using a proper JOIN table ON clause, not table1, table2 WHERE.

In your case the problem is fixed using LEFT JOIN

SELECT * FROM posts p
  LEFT JOIN comments c ON c.id_post = p.id_post
  GROUP BY p.id_post
  ORDER BY
  CASE 
   WHEN c.creation_date IS NOT NULL THEN c.creation_date ELSE p.creation_date 
  END
ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top