There is the orders table with columns: status
, created_at
Status column having values: new, processing, other.
The issue is to select all orders, first of all with status new after that with status processing, after that all others.
New and processing orders should be sorted by created_at
ascending order, all other orders sorted by created_at
descending order.
I tried many different approaches, but stuck with each one.
For example tried combine with union two selects, but it turned out that union ignore selecting order in internal query.
Or other variant:
SELECT orders.status, orders.created_at FROM `orders` ORDER BY status = 'new' DESC, status = 'processing' DESC,
CASE
WHEN (orders.status='new' or orders.status='processing')
THEN -created_at
ELSE created_at
END;
Doesn't work too.
@ric in Firebird you can put an order by in a with clause, the effects are just not guaranteed (the sort might be retained when no other steps in the query plan cause a sort).
Answer: ORDER BY is a clause that is typically used along with SELECT queries in MySQL and is used to return the result set sorted in the given order against the given column or field in the table.
You can use the WHERE clause with or without the ORDER BY statement. You can filter records by finite values, comparison values or with sub-SELECT statements.
The ORDER BY clause is used to get the sorted records on one or more columns in ascending or descending order. The ORDER BY clause must come after the WHERE, GROUP BY, and HAVING clause if present in the query. Use ASC or DESC to specify the sorting order after the column name.
You can use this:
SELECT orders.status, orders.created_at
FROM `orders`
ORDER BY
status='new' DESC,
status='processing' DESC,
CASE WHEN status IN ('new', 'processing') THEN created_at END ASC,
CASE WHEN status NOT IN ('new', 'processing') THEN created_at END DESC
Please have a look at this fiddle. When status is in ('new', 'processing') the first case when will return the created date that will be ordered ascending, or null otherwise. When status is not in ('new', 'processing') the second case when will return the created date that will be in descending order.
This is working in Oracle. Please check if it works in MySQL too. Idea is to convert the created_at in desc order in case statement. multiplying -1 is not doing it. So give it a try. Also please replace sysdate to its mysql equivalent.
select orders.status, orders.created_at FROM orders
ORDER BY
CASE
WHEN (orders.status='new' or orders.status='processing')
THEN created_at end,
case when orders.status='other' then (sysdate - created_at)
END;
Output
STATUS CREATED_AT
processing 20-AUG-2015 22:11:24
processing 30-AUG-2015 22:11:24
new 30-AUG-2015 22:11:24
new 09-SEP-2015 22:11:24
other 10-AUG-2015 22:11:24
other 31-JUL-2015 22:11:24
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With