ThinkJet прав, что некоторые другие ответы не удовлетворяют требованию «держаться вместе».Однако я думаю, что это можно сделать, не прибегая к пользовательскому агрегату.
Пример данных
create table test (empno number, ename varchar2(20), trandate date, amt number);
insert into test values (100, 'Alison' , to_date('21-MAR-1996') , 45000);
insert into test values (100, 'Alison' , to_date('12-DEC-1978') , 23000);
insert into test values (100, 'Alison' , to_date('24-OCT-1982') , 11000);
insert into test values (101, 'Linda' , to_date('15-JAN-1984') , 16000);
insert into test values (101, 'Linda' , to_date('30-JUL-1987') , 17000);
insert into test values (102, 'Celia' , to_date('31-DEC-1990') , 78000);
insert into test values (102, 'Celia' , to_date('17-SEP-1996') , 21000);
insert into test values (103, 'James' , to_date('21-MAR-1996') , 45000);
insert into test values (103, 'James' , to_date('12-DEC-1978') , 23000);
insert into test values (103, 'James' , to_date('24-OCT-1982') , 11000);
insert into test values (104, 'Robert' , to_date('15-JAN-1984') , 16000);
insert into test values (104, 'Robert' , to_date('30-JUL-1987') , 17000);
Теперь определите конечную строку каждого сегмента empno (используя RANK, чтобы найти началои COUNT..PARTITION BY, чтобы найти номер в сегменте).
Затем используйте ceil / 4 из решения APC, чтобы сгруппировать их в «страницы».Опять же, как указывает ThinkJet, в спецификации есть проблема, поскольку она не учитывает ситуацию, когда в сегменте empno «держать вместе» больше записей, чем может поместиться на странице.
select empno, ename,
ceil((rank() over (order by empno) +
count(1) over (partition by empno))/6) as chunk
from test
order by 1;
Как указывает ThinkJet, это решение не является пуленепробиваемым.
drop table test purge;
create table test (empno number, ename varchar2(20), trandate date, amt number);
declare
cursor csr_name is
select rownum emp_id,
decode(rownum,1,'Alan',2,'Brian',3,'Clare',4,'David',5,'Edgar',
6,'Fred',7,'Greg',8,'Harry',9,'Imran',10,'John',
11,'Kevin',12,'Lewis',13,'Morris',14,'Nigel',15,'Oliver',
16,'Peter',17,'Quentin',18,'Richard',19,'Simon',20,'Terry',
21,'Uther',22,'Victor',23,'Wally',24,'Xander',
25,'Yasmin',26,'Zac') emp_name
from dual connect by level <= 26;
begin
for c_name in csr_name loop
for i in 1..11 loop
insert into test values
(c_name.emp_id, c_name.emp_name, (date '2010-01-01') + i,
to_char(sysdate,'SS') * 1000);
end loop;
end loop;
end;
/
select chunk, count(*)
from
(select empno, ename,
ceil((rank() over (order by empno) +
count(1) over (partition by empno))/25) as chunk
from test)
group by chunk
order by chunk
;
Таким образом, с размером фрагмента 25 и размером группы 11 мы получаемпрыгает туда, куда вписывается 33 человека, несмотря на ограничение в 25.Большие размеры чанков и небольшие группы должны делать это нечастым, но вы бы хотели иметь некоторую свободу действий.Так что, возможно, установите куски в 65 000 вместо того, чтобы идти до 65 536.