2014-01-23 81 views
7

我想在我的过程中使用函数LEAST来查找最小值。问题是,有些值可能是空值,因此,如果我做Oracle SQL中最小值但不为NULL

select least(NULL,0,1) from dual 

我得到的答案是NULL,这可能是正确的,是不是我很期待返回。我想获得最不真实的非零值。任何帮助不胜感激。

回答

1

我怀疑这实际上是您的查询。也许你正在做更像这样的事情?

select least(some_column) from dual 

如果是这样,就改成这样:

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

或者,如果你正在做一些更多的像这样的,你不能只用where过滤设置,

select least(expr1,expr2,expr3) from dual 

做到这一点:

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

其中12345是一个足够大的值,只有在所有其他表达式都是NULL时才会被选中。

+0

感谢@tenfour,我有比较多的结果其中一些将是空值。合并解决了我的问题。 –

+1

至少应该用至少2个参数调用,否则它是无用的;你最初的例子可能会让新手感到困惑。另外,如果所有参数都是NULL,那么返回'12345'(或者任何你使用的任意大数目)而不是NULL是一个等待发生的错误,恕我直言。 –

+0

我同意;实际上我觉得如果你想对这个集合进行这种控制,你应该真的使用子查询分解来旋转它,然后逻辑变得更加理智。 – tenfour

8

如果任何参数为NULL,您希望至少采用其他参数。如果所有参数都是NULL,则要返回NULL。

我可能会使用这样的两个参数:

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

它就启动> 2点的参数越来越难看,但:

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

在这一点我会开始考虑魔法值;但是这可能是越野车(例如,如果该值的一个合法魔法值):

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)); 
0

在三个“聚结”呼叫使用三个数量级三个表达式,并把这些在“最'调用将导致三个中的至少一个,忽略空,除非所有三个表达式都为空。

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

对不起,但接受的答案看起来更好 – Alexander

0

一种方法是定义LEAST/GREATEST FUNC的自己的版本:

-- here version for two params 
WITH FUNCTION least_improved(p1 IN NUMBER, p2 IN NUMBER) RETURN NUMBER IS 
BEGIN 
    IF p1 IS NULL THEN 
     RETURN p2; 
    ELSIF p2 IS NULL THEN 
     RETURN p1; 
    ELSE 
     RETURN LEAST(p1, p2); 
    END IF; 
END; 
SELECT least_improved(col1, col2) 
FROM table_name; 
/