views:

257

answers:

5

I have a simple task list which contains amongst others a title field and a deadline field. Some tasks got deadlines, other don't. Deadlines are simply stored with a MySQL date type.

But the tough part (for me anyway) is to sort the tasks in the correct order:

  1. Ascending deadlines
  2. The rest (maybe by ID, but not important)

Current query:

SELECT * FROM tasks ORDER BY deadline ASC

The deadline field is '0000-00-00' by default, so this query will show the tasks in the following order:

  1. Tasks with no deadlines
  2. Ascending deadlines

Can anybody point me in the right direction, or do I need to do multiple queries?

+2  A: 

One obvious possibility would be (in the application that creates the projects) set a deadline way in the future (say '9999-12-31') if the user doesn't enter a deadline. Of course, it's not clear whether you can change that code or not...

Jerry Coffin
Actually, field type date is default null, so you're right. I can change the code, but wouldn't it be easier to just solve it with an query.
rebellion
Probably -- if it is null to start with, then (as others have already pointed out) it's pretty trivial to handle it in the query. For that matter, you *can* handle it in the query if it's 0000-00-00, but I'd be more leary about that -- I can just about see somebody actually entering that (if you let them) to mean "immediately".
Jerry Coffin
+2  A: 
SELECT * FROM tasks
ORDER BY CASE WHEN deadline = '0000-00-00'
              THEN '9999/09/09' 
              ELSE deadline 
         END ASC

When sorting, replace '0000-00-00' by a 'big' datetime value: '9999/09/09'.

najmeddine
This works like charm, thanks!
rebellion
+1  A: 

Is it really 0000-00-00? The docs says:

"The supported range is '1000-01-01' to '9999-12-31'. "

I would consider storing NULL in deadline for those that do not have one.

SELECT * FROM tasks ORDER BY ifnull(deadline, '9999-12-31') ASC
Jonas Elfström
You're right. By default it's null, but the code inserts 0000-00-00, but I can change this. Although the field type is not datetime, but date.
rebellion
Did you try out the query?
Jonas Elfström
A: 

use a where to hide your tasks without a deadline:

SELECT * FROM tasks WHERE deadline != '0000-00-00' ORDER BY deadline
knittl
That doesn't look like valid SQL to me and MySQL seems to agree.
Jonas Elfström
wops, i switched where and order.
knittl
As far as I can tell he wants to list all tasks but with the ones without deadline sorted after the ones with.
Jonas Elfström
A: 

might be more performant(could use your index on deadline field, putting a CASE WHEN on ORDER BY clause might not use your index on deadline field):

SELECT 1 /* no deadlines first */ as sort, * 
FROM tasks 
WHERE deadline = '0000-00-00' OR deadline IS NULL -- no deadlines
UNION
SELECT 2 /* the rest, with deadlines */ as sort, * 
FROM tasks 
WHERE deadline <> '0000-00-00' -- with deadlines

ORDER BY sort, deadline -- this will apply to both results

or if you want najmeddine concise query, improve his/her query, use this mysqlism to make it shorter:

SELECT * FROM tasks
ORDER BY deadline <> '0000-00-00' /* no deadlines first */, deadlines
Michael Buen