Reputation: 2823
On a website, I have got a list of Items I am struggling to sort with MySQL.
Some of the items are "expired" (their end_at is in the past), and I'd like to retrieve them, but after the "active" items (their end_at can be either NULL or in the future).
I would like to be able to further sort items according to another field, let's say "views" (to get the most popular ones first)
Basically, this is what I'd like to get :
So far, this is what I have tried:
SELECT name, end_at
FROM items
ORDER BY (end_at IS NULL OR end_at > CURDATE()), views DESC;
Doesn't work : even the first returned item is expired.
Upvotes: 0
Views: 794
Reputation: 204756
You almost got it. A condition in MySQL returns 0
or 1
. And since 0
comes before 1
you have to either sort desc
SELECT name,end_at FROM items
ORDER BY (end_at IS NULL OR end_at > CURDATE()) DESC,
views DESC;
or negate the condition to get the desired result
SELECT name,end_at FROM items
ORDER BY end_at IS NOT NULL AND end_at < CURDATE() ASC,
views DESC;
Upvotes: 1
Reputation: 2823
I just found a way :
SELECT *
FROM items
ORDER BY CASE
WHEN (end_at IS NULL OR end_at > CURDATE())
THEN 0
ELSE 1
END, views DESC;
The CASE WHEN affects a value on each row, according to an expression. The sort is done as usual, using this computed value.
Upvotes: 0