选择条款

时间:2018-02-12 23:41:45

标签: sql oracle hsqldb min

有人可以帮我写一个sql查询,该查询应该根据以下条件执行oracle min函数。

例如,对于列值

  • 0,0,0,0然后输出应为0
  • 0,null,0,null然后输出应为o
  • 0,2,4,5,6然后输出应为2(注意我们在这里排除零)
  • 0,2,null,4,5然后输出应该是2(这里我们不包括零)
  • null,null,null,null则输出应为null。

我编写的查询已满足上述所有情况但在最后一种情况下失败,因为所有列值都为null。它返回0而不是返回null。有人可以修改下面的查询以适应最后一个案例吗?

从tablename中选择NVL(MIN(NULLIF(列名,0)),0);

还请记住,查询应该在oracle和hsqldb中运行,因为我们使用hsql db来运行junits。

2 个答案:

答案 0 :(得分:1)

如果您的查询满足所有4个案例,那么只需一个案例即可解决您的问题。

SELECT CASE WHEN MIN(COLUMNNAME) IS NULL THEN NULL ELSE NVL(MIN(NULLIF(COLUMNNAME,0)),0) END FROM TABLENAME;

注意: - 假设您的查询满足所有情况,除了第5。

答案 1 :(得分:0)

我将在下面显示一个包含两列IDVAL的输入表,以说明各种可能性。您希望每个ID(甚至整个表)都有一个结果,因此这必须是GROUP BY和某些聚合函数的作业。您想要区分三种类型的值:大于零,零和null(按此顺序);你想选择"最高优先级组"对于每个ID(按此优先级顺序)存在,并且仅对于该优先级组,您希望选择最小值。这是完全聚合FIRST/LAST函数的作用。按三个班级排序"对于值,我们在聚合CASE函数的ORDER BY子句中使用LAST表达式。

下面的WITH子句不是解决方案的一部分 - 我只包含它来创建测试数据(在您的实际情况中,使用您的实际表和列名称并删除整个WITH子句)。

with
  inputs ( id, val ) as (
    select 1, 0    from dual union all
    select 1, 0    from dual union all
    select 1, 0    from dual union all
    select 2, 0    from dual union all
    select 2, null from dual union all
    select 2, 0    from dual union all
    select 3, 0    from dual union all
    select 3, 2    from dual union all
    select 3, 5    from dual union all
    select 4, 0    from dual union all
    select 4, 3    from dual union all
    select 4, null from dual union all
    select 5, null from dual union all
    select 5, null from dual
  )
select   id,
         min(val) keep (dense_rank last order by case when val > 0 then 2
                                                      when val = 0 then 1
                                                      else              0 
                                                 end
                       ) as min_val
from     inputs
group by id
order by id
;    

        ID    MIN_VAL
---------- ----------
         1          0
         2          0
         3          2
         4          3
         5