Oracle - 用于创建间隔的理论sql查询

时间:2014-08-06 14:33:03

标签: sql oracle connect-by

是否可以通过ORACLE中的sql查询解决这种情况?

我有一张这样的表:

TYPE    UNIT
A       230
B       225
C       60
D       45
E       5
F       2

我需要将单位分成三个(可变的)相同'(大小相等)的间隔,并预先算出计数?这意味着:

0   - 77    -> 4
78  - 154   -> 0
155 - 230   -> 2

2 个答案:

答案 0 :(得分:3)

您可以使用最大值和连接查询来生成每个范围的上限值和下限值:

select ceil((level - 1) * int) as int_from,
  floor(level * int) - 1 as int_to
from (select round(max(unit) / 3) as int from t42)
connect by level <= 3;

  INT_FROM     INT_TO
---------- ----------
         0         76 
        77        153 
       154        230 

然后对原始表执行左外连接以对每个范围进行计数,因此您获得中间范围的零值:

with intervals as (
  select ceil((level - 1) * int) as int_from,
    floor(level * int) - 1 as int_to
  from (select round(max(unit) / 3) as int from t42)
  connect by level <= 3
)
select i.int_from || '-' || i.int_to as range,
  count(t.unit)
from intervals i
left join t42 t
on t.unit between i.int_from and i.int_to
group by i.int_from, i.int_to
order by i.int_from;

RANGE      COUNT(T.UNIT)
---------- -------------
0-76                   4 
77-153                 0 
154-230                2 

答案 1 :(得分:2)

是的,这可以在Oracle中完成。困难的部分是边界的定义。您可以对值为1,2和3的序列使用最大值和一些算术。

之后,剩下的就是cross join和聚合:

with bounds as (
      select (case when n = 1 then 0
                   when n = 2 then trunc(maxu / 3)
                   else trunc(2 * maxu / 3)
              end) as lowerbound,
             (case when n = 1 then trunc(maxu / 3) 
                   when n = 2 then trunc(2*maxu / 3)
                   else maxu
              end) as upperbound
      from (select 1 as n from dual union all select 2 from dual union all select 3 from dual
           ) n cross join
           (select max(unit) as maxu from atable t)
     )
select b.lowerbound || '-' || b.upperbound,
       sum(case when units between b.lowerbound and b.upperbound then 1 else 0 end)
from atable t cross join
     bounds b
group by b.lowerbound || '-' || b.upperbound;