У меня есть таблица 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» я хотел бы выбрать serial_no в одном столбце со значениями «1-3», «5», «7-10». Выбранный столбец должен находиться в диапазоне от минимального до максимального в порядке возрастания.
Как вы думаете, зачем вам нужна хранимая процедура?
Это может быть процедура ...
Я отредактировал ваш вопрос, чтобы лучше описать результат. Не могли бы вы проверить, соответствует ли модификация вашим ожиданиям?
Thx trincot, твой титул лучше моего





Вы мог делаете это без pl / sql, используя запрос с некоторыми общими табличными выражениями (предложение 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);
Вы также должны объяснить логику группировки ...