Oracle SQL中的最小值但不是NULL

时间:2014-01-23 16:21:30

标签: sql oracle

我想在我的程序中使用LEAST函数来找到最小值。问题是某些值可能是NULL,所以如果我这样做

select least(NULL,0,1) from dual

我得到的答案是NULL,这可能是正确的,不是我期望返回的东西。我想获得最不真实的非零值。非常感谢任何帮助。

7 个答案:

答案 0 :(得分:12)

如果任何参数为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));

答案 1 :(得分:3)

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

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时才会被选中。

答案 2 :(得分:0)

在三个'coalesce'调用中使用三个顺序中的三个表达式并将它们放在'least'调用中将导致三个中的至少三个,忽略null,除非所有三个表达式都为null。

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

答案 3 :(得分: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;
/

答案 4 :(得分:0)

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

将从第1列到第N列的最低值返回

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

将从第1列返回最大值到N

INFINITY:至少在db2中,你有'无穷大'值,可以用作所有的最大数和“无穷”,可以用作所有的最低数。 (oracle有不同类型的无限我被告知)

COALESCE:此函数将从参数列表返回非空的第一个参数,例如:COALESCE(NULL,NULL,NULL,NULL,NULL,1,2,3,4,5)将返回1(第一个不为null的参数);

因此在此查询中使用coalesce将null值替换为无穷大值,确保此值不会被选为最低值之一,除非所有列都具有null值,在这种情况下查询将返回无穷大而不是null

从查询中删除无穷大结果,只需添加where子句检查所有值是否为null,您也可以使用coalesce函数执行此操作:

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

答案 5 :(得分:0)

如果您有很多想要最小值和最大值的列,则可以将它们UNPIVOT分解为单个列,这样就很简单;从单列中排除NULL,并使用MIN()或MAX()获得所需的内容。

我需要使用大约50个日期列(这不是一个很好的数据库设计)来完成此操作,UNPIVOT似乎是最明智/最实用的方式

答案 6 :(得分:0)

SELECT least(1, 2, 3, nvl(NULL,4)) FROM dual

返回:1

SELECT GREATEST(1, 2, 3, nvl(NULL,0)) FROM dual

返回:3