KimchiMan KimchiMan - 3 months ago 8
SQL Question

Order by clause for Many 2 Many in MySQL

I have tables/records like this:

Table: COMMENTS
---------------------------------------------
COMMENT_ID | CONTENT | CREATE_DATE
---------------------------------------------
1 | Content 1 | 2016-09-01
2 | Content 2 | 2016-09-02
3 | Content 3 | 2016-09-03
4 | Reply to Content 2 | 2016-09-04
5 | Reply to Content 1 | 2016-09-05
6 | Reply to Content 2 | 2016-09-03


Table: REPLY_COMMENTS
---------------------------------
COMMENT_ID | REPLY_TO_COMMENT_ID
---------------------------------
4 | 2
5 | 1
6 | 2


And I'd like to show the records like this order:

---------------------------------------------
COMMENT_ID | CONTENT | CREATE_DATE
---------------------------------------------
1 | Content 1 | 2016-09-01
5 | Reply to Content 1 | 2016-09-05
2 | Content 2 | 2016-09-02
6 | Reply to Content 2 | 2016-09-03
4 | Reply to Content 2 | 2016-09-04
3 | Content 3 | 2016-09-03


So the 'reply' contents should be under the parent's content - but the reply contents also should be ordered by CREATE_DATE.

Basically, I want to put together: content and reply with order of CREATE_DATE.

I wrote the query like this:

SELECT comment.*
FROM COMMENTS comment
LEFT JOIN REPLY_COMMENTS reply_comment ON reply_comment.COMMENT_ID = comment.COMMENT_ID

ORDER BY (SOMETHING SHOULD BE HERE), comment.CREATE_DATE ASC


I can't write the order by clause with my current knowledge - please help me out (I'm using MySQL).

I only want to use the
COMMENTS.CREATE_DATE
field - don't want to use
COMMENT_ID
field since it's primary key (is it even possible?).

Answer
SELECT t1.COMMENT_ID,
       t1.CONTENT,
       t1.CREATE_DATE
FROM COMMENTS t1
LEFT JOIN REPLY_COMMENTS t2
    ON t1.COMMENT_ID = t2.COMMENT_ID
ORDER BY COALESCE(t2.REPLY_TO_COMMENT_ID, t1.COMMENT_ID),
         t1.CREATE_DATE

Explanation:

The ORDER BY clause uses two terms for ordering. The first COALESCE term will return the COMMENT_ID of the parent message (for both parents and single descendant children). The reason this works is that for children it will used the joined ID, and for parents, finding NULL it will also default to the parent ID. The second ordering term uses the creation date, under the assumption that all replies to a post will occur after the original post.