聚合序列中的数字
Aggregate numbers that are in sequence
我有一个 table 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
分组依据 part_no
。因此,对于第 "A" 号零件,我想 select 在一列中 serial_no
的值为“1-3”、“5”、“7-10”。所选列的范围应从最小值到最大值并按升序排列。
你 可以 在没有 pl/sql 的情况下使用一些常见的 table 表达式(with
子句)进行查询。它看起来像这样:
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
这是一个间隙和孤岛问题,您可以通过对行编号并从序列号中减去这些数字来解决。这为您提供了所需的组。
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);
我有一个 table 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
分组依据 part_no
。因此,对于第 "A" 号零件,我想 select 在一列中 serial_no
的值为“1-3”、“5”、“7-10”。所选列的范围应从最小值到最大值并按升序排列。
你 可以 在没有 pl/sql 的情况下使用一些常见的 table 表达式(with
子句)进行查询。它看起来像这样:
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
这是一个间隙和孤岛问题,您可以通过对行编号并从序列号中减去这些数字来解决。这为您提供了所需的组。
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);