如何在oracle sql中对一系列数字进行分组,并提供特定的数字

时间:2016-01-13 11:12:56

标签: sql oracle plsql

我有一系列以下列格式存储在oracle表中的数字。

Emp_ID
1
2
3
4
5
6
7
8
9
10
14
15
16
17
18
31
32
33
34
35
36
41
42

我想用固定数字(如7)对此列表进行分组,并按以下格式获取输出:

Range         Total
1-7            7
8-10,14-17     7
18-18,31-36    7
41-42          2

3 个答案:

答案 0 :(得分:0)

如果您需要示例中显示的范围表示:

-- test data
with data(empid) as
 ( -- complete list 1..42
  select level
    from dual
  connect by level <= 42
  minus (
         -- minus gaps
         select level
           from dual
          where level between 11 and 13
         connect by level <= 42
         union
         select level
           from dual
          where level between 19 and 30
         connect by level <= 42
         union
         select level
           from dual
          where level between 37 and 40
         connect by level <= 42))

-- select:  
select listagg(case
                 when minempid = maxempid then
                  minempid || ' '
                 else
                  (minempid || '-' || maxempid)
               end,
               ', ') within group(order by minempid),
       sum(cnt)
  from (select grp,
               seq,
               min(empid) as minempid,
               max(empid) as maxempid,
               count(*) cnt
          from (select empid, rn, empid - rn as seq, ceil(rn / 7) as grp
                  from (select empid, row_number() over(order by empid) rn
                          from data))
         group by grp, seq)
 group by grp;

答案 1 :(得分:0)

在Oracle 11g中,您可以使用listagg()和分析函数:

SQLFiddle demo

with t1 as (
    select emp_id id,row_number() over (order by emp_id) rn from test),
  t2 as (
    select id, rn, floor((rn-.1)/7) grp,
           min(id) over (partition by floor((rn-.1)/7), id-rn)||'-'||
           max(id) over (partition by floor((rn-.1)/7), id-rn) rng
      from t1),
  t3 as (select grp, rng, min(rn) rn, count(1) cnt from t2 group by grp, rng)
select listagg(rng, ', ') within group (order by rn) range, sum(cnt) total
  from t3 group by grp

答案 2 :(得分:0)

另一个例子是使用案例和该范围的分组来确定每个值的范围:

select rng, count(1) from (
  select 
    case  
      when emp_id between 1 and 7 then 'range 1'
      when emp_id between 8 and 10 or emp_id between 14 and 17 then 'range 2'
      when emp_id between 18 and 18 or  emp_id between 31 and 36 then 'range 3'
      when emp_id between 41 and 42 then 'range 4'
      else 'no range'
    end as rng
  from employees) 
group by rng;