Hi everyone...newbie here...but frequent reader (particularly of Mr. Kulash)
So this is what I want to do: I want to take a set of rows and group them by a specific # per group (group 1, group 2, etc.)
In the example here it is a set of five rows per group. Now in reality I won't know the # of records
But I will know:
the # per group
the total # of "complete groups" (where they all have the same # of records)
and based on that the # of records that go into the final group
with a as
(
select level id from dual connect by level <=101 --create X # of rows
),
b as
(
select id
,5 as per_grp
,ceil(count(id) over ()/5) as t_buckets -- total # of buckets needed
,trunc(count(id) over ()/5) as s_buckets -- starting # of buckets
from a
),
c as
(
select id
,per_grp
,t_buckets
,s_buckets
,case when id <= (per_grp * s_buckets) then s_buckets end as m_buckets --maximum # of complete buckets
from b
)
select
id
,per_grp
,t_buckets
,s_buckets
,m_buckets
,case when m_buckets is not null then ntile(m_buckets) over (partition by m_buckets order by id)
else t_buckets
end as final_grp
from c
The final output would be something like this (I cut down the row #'s)
| id | final_grp |
| 1 | 1 |
| 2 | 1 |
| 3 | 1 |
| 4 | 1 |
| 5 | 1 |
| 6 | 2 |
| 7 | 2 |
| 8 | 2 |
| 9 | 2 |
| 10 | 2 |
| 11 | 3 |
| 12 | 3 |
| 13 | 3 |
This seems to work, even if the # of records is less than the grouping #. I guess I 'm looking for guidance. Is using the Ntile function in a case statement with a null condition a big mistake? Would there be a better way of doing this?
I originally started here:
I'm using:
Oracle Database 11g Enterprise Edition Release 11.2.0.3.0 - 64bit Production
PL/SQL Release 11.2.0.3.0 - Production
CORE 11.2.0.3.0 Production
TNS for IBM/AIX RISC System/6000: Version 11.2.0.3.0 - Production
NLSRTL Version 11.2.0.3.0 - Production
Any help would be appreciated.
Cheers!