tags:

views:

79

answers:

3

Ok, I have to put null values last. The query should run under Oracle and MySQL.

I've already came up with

ORDER BY

    CASE WHEN some_table.ord IS NULL THEN 9999999999 ELSE some_table.ord END

I should use value > max(some_table.ord) instead of 9999999999.

I think subquery to determine this value is too ugly here.

If this was C++ I can use some macro like INT_MAX for this purpose. Can you name its cross-DBMS SQL twin?

UPDATE

the question is if can I put something .. beautiful instead of 9999999999, so that query will work both in Oracle and MySQL,

not how to put null values last

+4  A: 

In Oracle, it's simply

ORDER BY some_table.ord NULLS LAST
ammoQ
unfortunately, this is not available on MySQL
Thilo
+5  A: 

Use an extra column for the null flag:

order by 
   case when some_table.ord is null then 2 else 1 end ,
   some_table.ord

Or, if you have enough knowledge of the values that this column can take, just hard-code a number that is larger than anything in there:

order by coalesce(some_table.ord, 9999999999)
Thilo
Is that coalesce better or worse performance than the case statement? For some reason I lean toward the case statement being better.
Emtucifor
@Emtucifor - I wouldn't want to have to live on the difference between a CASE() and a COALESCE(). The CASE() has the advantage of not requiring a hardcoded maximum value, but it is more typing.
APC
@APC - I'm all for less typing (believe me, I have a pet peeve about this) but if there's a performance implication, I don't really care if I have to type a little extra.
Emtucifor
@Emtucifor - perhaps I was too subtle. There is no performance implication. Under the hood they are all switches.
APC
@APC - Too subtle, maybe, but incorrect for sure. I tested the two expressions against a table with 143 million rows (requiring > 3.2 million reads) and the the Coalesce() version consistently took 5 to 8% more CPU, average 7.24% more CPU. Here are my raw numbers for 3 executions: 124780,134579; 124843,135158; 128750,136062. Given that IsNull expands to a CASE statement and that `Coalesce(dbo.ExpensiveFunction(), '')` is VERY different from `IsNull(dbo.ExpensiveFunction(), '')` (look at the execution plans) this is not surprising to me.
Emtucifor
A: 

Something like the following might work:

SELECT S.VAL1, S.VAL2, S.VAL3, COALESCE(S.ORD, O.MAX_ORD+1) AS ORD
  FROM SOME_TABLE S,
       (SELECT MAX(ORDER) AS MAX_ORD FROM SOME_TABLE) O
  WHERE S.whatever = whichever AND
        S.something <> something_else
  ORDER BY ORD

Not sure if MySQL allows sub-queries in the FROM list. The idea here is to avoid the use of a magic value to handle the NULL case.

Share and enjoy.

Bob Jarvis
There's no need to go query the max, which is a performance hit. Just use Thilo's technique.
Emtucifor