案例陈述的替代方案

时间:2015-07-02 05:02:03

标签: sql oracle

除了在Oracle中使用CASE语句之外,我还需要您编写SQL查询的建议。我有一个名为SYSTEM_SPECS的表,其中包含以下数据

Customer_Id     Disk_space_allocated
C001                    44G
C002                    1300G
C003                    1503G
C004                    1780G

我使用Oracle case语句编写了以下SQL查询,根据customer_id

的范围计算disk_space_allocated的数量
select

  case

    when to_number(substr(disk_space_allocated,0,length(disk_space_allocated) -1  )) <= 300

    then '1-300'

    when to_number(substr(disk_space_allocated,0,length(disk_space_allocated) -1  )) <= 500

    then '300-500'

    when to_number(substr(disk_space_allocated,0,length(disk_space_allocated) -1 )) <= 700

    then '500-700'

    when to_number(substr(disk_space_allocated,0,length(disk_space_allocated) -1  )) <= 900

    then '700-900'

    else '900+'

  end      as diskallocated,

  count(*) as number_of_customers

from SYSTEM_SPECS

group by

  case

    when to_number(substr(disk_space_allocated,0,length(disk_space_allocated) -1 )) <= 300

    then '1-300'

    when to_number(substr(disk_space_allocated,0,length(disk_space_allocated) -1 )) <= 500

    then '300-500'

    when to_number(substr(disk_space_allocated,0,length(disk_space_allocated) -1 )) <= 700

    then '500-700'

    when to_number(substr(disk_space_allocated,0,length(disk_space_allocated) -1 )) <= 900

    then '700-900'

    else '900+'

  end;

这个查询可以写成其他形式吗?

1 个答案:

答案 0 :(得分:1)

首先,你的逻辑是错误的,你正在计算&lt; = 700并且说它在500-700之间,如果它是&lt; = 700则默认它是&lt; = 500且&lt; = 300。然后我们不能在500-700之间调用它。请尝试以下查询

select
  count(*) as number_of_customers,b.var as "Less Than below value"
from SYSTEM_SPECS a,
(select 300 + (level-1)*200 var
 from dual
connect by level <= 4) b
where to_number(substr(a.disk_space_allocated,0,length(a.disk_space_allocated) -1 )) <= b.var
group by b.var
order by b.var

在@Alex

的帮助下,您的问题的最终答案
with ranges as (
      select case when level = 1 then 0 else 100 end + (level-1) * 200 low_value,
        case when level = 5 then 99999999 else 100 + (level) * 200 end high_value
      from dual
      connect by level <= 5
    )
    select r.low_value ||'-'|| r.high_value as diskallocated,
      count(*) as number_of_customers
    from ranges r
    left join system_specs ss
    on to_number(substr(ss.disk_space_allocated, 1, length(ss.disk_space_allocated) -1 )) > r.low_value
    and to_number(substr(ss.disk_space_allocated, 1, length(ss.disk_space_allocated) -1 )) <= r.high_value
    group by r.low_value, r.high_value
    order by r.low_value, r.high_value;