Least value but not NULL in Oracle SQL

If any argument is NULL, you want to take the least of the other argument(s). If all arguments are NULL, you want to return NULL.

I might use something like this for two arguments:

LEAST(NVL(colA,colB), NVL(colB,colA))

It starts getting ugly for >2 arguments though:

LEAST(COALESCE(colA,colB,colC)
     ,COALESCE(colB,colA,colC)
     ,COALESCE(colC,colA,colB))

At which point I'd start considering magic values; but this can be buggy (e.g. what if one of the values legitimately is the magic value?):

SELECT CASE WHEN r = maxv THEN NULL ELSE r END AS result
FROM   (SELECT LEAST(NVL(:colA,maxv)
                    ,NVL(:colB,maxv)
                    ,NVL(:colC,maxv)) AS r, maxv
        FROM   (SELECT 9.999999999999999999999999999999999999999e125
                       AS maxv FROM DUAL));

Lowest value from column 1 to N:

SELECT
    LEAST(COALESCE(Col1, BINARY_DOUBLE_INFINITY),
          COALESCE(Col2, BINARY_DOUBLE_INFINITY),
          ... ,
          COALESCE(ColN, BINARY_DOUBLE_INFINITY)
    )
FROM MY_TABLE

Greatest value from column 1 to N:

SELECT
    GREATEST(
        COALESCE(Col1, -BINARY_DOUBLE_INFINITY),
        COALESCE(Col2, -BINARY_DOUBLE_INFINITY),
        ..., 
        COALESCE(ColN, -BINARY_DOUBLE_INFINITY)
    )
FROM MY_TABLE

To remove the infinity results from the query, just add the where clause checking if all the values are null. You can do that using the coalesce function as well:

WHERE COALESCE(Col1, Col2, ..., ColN) IS NOT NULL

I doubt that's actually your query. Maybe you're doing something more like this?

select least(some_column) from dual

If so, change it to this:

select least(some_column) from dual where some_column is not null

Or, if you're doing something more like this, where you can't just use where to filter the set,

select least(expr1,expr2,expr3) from dual

do this:

select least(coalesce(expr1, 12345), coalesce(expr2, 12345), coalesce(expr3, 12345)) from dual

Where 12345 is a value big enough that it would only be chosen if all other expressions are NULL.


Using the three expressions in three orders in three 'coalesce' calls and putting these in the 'least' call will result the least of three, ignoring null unless all three expressions are null.

select least(coalesce(expr1, expr2, expr3), coalesce(expr2, expr3, expr1), coalesce(expr3, expr1, expr2)) from dual

Tags:

Sql

Oracle