Reputation: 117
I have a table which stores info about some events.
I would like to list those events but I would like the upcoming events to be displayed first and in ascending order while the past ones to be displayed below in descending order.
I would probably like to do something like this:
(SELECT * FROM events WHERE date > NOW() ORDER BY date ASC)
UNION
(SELECT * FROM events WHERE date < NOW() ORDER BY date DESC)
I checked MySQL doc and found out that UNION generally works with unordered set of rows so ordering withing each of the SELECTs is quite useless. Neither UNION ALL seems to do the job.
After googling a little bit, I know how to order the rows according to which SELECT produced them, however, I still don't know how to order them by same column in different order.
I guess I could very well just execute two SELECTs, one for upcoming events, one for past ones. But I really wonder whether there's a possibility to do it with just one query.
Is there anything you could suggest?
Upvotes: 4
Views: 731
Reputation: 108390
To answer the more general question, the UNION
operation is not guaranteed to preserve any order of any retrieved rows. To get rows returned in a specific order, the only guarantee you have is to use an ORDER BY
clause on the query (the outermost SELECT statement).
Upvotes: 0
Reputation: 183280
I don't think you need a UNION
for this. You should be able to write:
SELECT *
FROM events
ORDER
BY CASE WHEN date < NOW() THEN date ELSE NOW() END DESC,
date ASC
;
The CASE WHEN date < NOW() THEN date ELSE NOW() END DESC
part of the ORDER BY
ensures that upcoming events come first, and ensures that past events show up in the desired order, but doesn't affect the relative order of upcoming events. The date ASC
part is a fallback criterion that handles that part.
(Disclaimer: not tested.)
Upvotes: 3