聚合顺序编号

时间:2018-11-13 14:50:25

标签: oracle plsql gaps-and-islands

我有一个表SELECT * FROM `App_info` WHERE `when` > '2018-11-05' GROUP BY `typeInfo` , `str2` ORDER BY `App_info`.`when` ASC 和列part_tab

serial_no

我想按顺序将PART_NO SERIAL_NO A 1 A 2 A 3 A 5 A 7 A 8 A 9 A 10 值汇总到一行:

serial_no

通过PART_NO SERIAL_NO A 1-3 A 5 A 7-10 进行分组。因此,对于零件编号“ A”,我想在一列中选择值{1-3“,” 5“,” 7-10“的part_no。所选列的范围应从最小到最大,并且应按升序排列。

2 个答案:

答案 0 :(得分:1)

这是一个空白和孤岛的问题,您可以通过对行进行编号并从序列号中减去这些数字来解决。这将为您提供所需的组。

select
  part_no,
  case when min(serial_no) = max(serial_no)
    then to_char(min(serial_no))
    else min(serial_no) || '-' || max(serial_no)
  end as serial_nos
from
(
  select
    part_no,
    serial_no,
    serial_no - row_number() over (partition by part_no order by serial_no) as grp
  from mytable
)
group by part_no, grp
order by part_no, min(serial_no);

答案 1 :(得分:0)

使用带有一些常用表表达式(with子句)的查询,您可以在不使用pl / sql的情况下执行此操作。看起来像这样:

with add_break as (
    select part_no, 
           serial_no,
           serial_no-1-lag(serial_no,1,0) over (partition by part_no order by serial_no) brk
    from part_tab
),
add_group as (
    select add_break.*, 
           sum(brk) over (partition by part_no order by serial_no) as grp
    from   add_break
)
select part_no,
       case when min(serial_no) = max(serial_no) then to_char(min(serial_no))
            else to_char(min(serial_no)) || '-' || to_char(max(serial_no))
       end range
from   add_group
group by part_no, grp
order by 1, 2

输出示例数据:

part_no | range
--------+------
   A    | 1-3
   A    | 5
   A    | 7-10