views:

311

answers:

4

Hi,

Currently I am doing a very basic OrderBy in my statement.

SELECT * FROM tablename WHERE visible=1 ORDER BY position ASC, id DESC

The problem with this is that NULL entries for 'position' are treated as 0. Therefore all entries with position as NULL appear before those with 1,2,3,4. eg:

NULL, NULL, NULL, 1, 2, 3, 4

Is there a way to achieve the following ordering:

1, 2, 3, 4, NULL, NULL, NULL.

Many Thanks,

JonB

A: 

You can swap out instances of NULL with a different value to sort them first (like 0 or -1) or last (a large number or a letter)...

SELECT field1, IF(field2 IS NULL, 9999, field2) as ordered_field2
  FROM tablename
 WHERE visible = 1
 ORDER BY ordered_field2 ASC, id DESC
Langdon
This won't solve the problem as the index referenced in ORDER BY will not be affected by replacing values in the SELECT statement, and thereby won't correct the ordering. Also, check out the COALESCE function, which is functionally equivalent to your use of the IF function.
Dustin Fineout
If you alias the IF statement properly, the rows are ordered as you'd expect. I fixed my example.
Langdon
+3  A: 

Something like

SELECT * FROM tablename where visible=1 ORDER BY COALESCE(position, 999999999) ASC, id DESC

Replace 999999999 with what ever the max value for the field is

DrewM
A: 

You can coalesce your NULLs in the ORDER BY statement:

select * from tablename
where <conditions>
order by
    coalesce(position, 0) ASC, 
    id DESC

If you want the NULLs to sort on the bottom, try coalesce(position, 100000). (Make the second number bigger than all of the other position's in the db.)

Seth
A: 

You can use the COALESCE function to check if the position index is NULL and, if so, replace it with some value with a higher collation than any number (such as a letter). Make this replacement within the ORDER BY statement so that it actually affects sorting. This will have no effect upon the selected column values retrieved (that would have to be done within the SELECT statement).

SELECT * FROM tablename WHERE visible=1 ORDER BY COALESCE(position,'Z') ASC, id DESC
Dustin Fineout