Can someone please help me out, I stuck here.
Given
AMOUNT CUSTOMER_NUMBER GROUPID SEQF
1000+ 5555 51 2
1000+ 5555 52 3
1000+ 5555 55 4
1000+ 5555 56 4
1000+ 5555 57 4
1000+ 5555 58 2
1000+ 5555 59 4
1000+ 5555 61 2
2000+ 6666 55 2
.
.
.
.
By considering AMOUNT and CUSTOMER_NUMBER columns, here creating group within 7 GROUPID Numbers
For e.g. 1st Group for 5555 CUSTOMER_NUMBER -> (51 to 57 GROUP ID), 2nd Group for 5555 CUSTOMER_NUMBER (58 to 61 GROUP ID), 3rd Group for 6666 CUSTOMER_NUMBER (55 GROUP ID)
Needed:
IF SEQF >=2 in 1st Group in any of the GROUPID from 51 to 57 then consider COUNT(SEQF) = 1
IF SEQF >=2 in 2nd Group in any of the GROUPID from 58 to 61 then consider COUNT(SEQF) = 1
so total here
AMOUNT CUSTOMER_NUMBER COUNT(SEQF)
1000+ 5555 2
IF SEQF >=2 in 3rd Group in any of the GROUPID from 55 then consider COUNT(SEQF) = 1
AMOUNT CUSTOMER_NUMBER COUNT(SEQF)
2000+ 6666 1
Desired Output
AMOUNT CUSTOMER_NUMBER COUNT(SEQF)
1000+ 5555 2
2000+ 6666 1
None of the other answers solve the problem where there are gaps between groups (they just assume groups are contiguous). This will skip gaps and put the groupid
into ranges of 7.
Oracle Setup:
create table data(amount, customer_number, groupid, seqf) as (
select '1000+', 5555, 51, 2 from dual union all
select '1000+', 5555, 52, 3 from dual union all
select '1000+', 5555, 55, 4 from dual union all
select '1000+', 5555, 56, 4 from dual union all
select '1000+', 5555, 57, 4 from dual union all
select '1000+', 5555, 60, 2 from dual union all
select '1000+', 5555, 61, 4 from dual union all
select '1000+', 5555, 65, 2 from dual union all
select '1000+', 5555, 69, 2 from dual union all
select '2000+', 6666, 55, 2 from dual );
Query 1:
This finds the groups:
SELECT amount,
customer_number,
groupid,
groupid + 6 AS max_groupid
FROM (
SELECT d.*,
MIN( groupid )
OVER ( PARTITION BY amount, customer_number )
AS min_groupid,
MIN( groupid )
OVER (
PARTITION BY amount, customer_number
ORDER BY groupid
RANGE BETWEEN 7 FOLLOWING AND UNBOUNDED FOLLOWING
)
AS next_groupid
FROM data d
)
START WITH groupid = min_groupid
CONNECT BY PRIOR amount = amount
AND PRIOR customer_number = customer_number
AND PRIOR next_groupid = groupid
which outputs:
AMOUNT | CUSTOMER_NUMBER | GROUPID | MAX_GROUPID :----- | --------------: | ------: | ----------: 1000+ | 5555 | 51 | 57 1000+ | 5555 | 60 | 66 1000+ | 5555 | 69 | 75 2000+ | 6666 | 55 | 61
Query 2:
This counts the groups:
SELECT amount,
customer_number,
COUNT(*)
FROM (
SELECT d.*,
MIN( groupid )
OVER ( PARTITION BY amount, customer_number )
AS min_groupid,
MIN( groupid )
OVER (
PARTITION BY amount, customer_number
ORDER BY groupid
RANGE BETWEEN 7 FOLLOWING AND UNBOUNDED FOLLOWING
)
AS next_groupid
FROM data d
)
START WITH groupid = min_groupid
CONNECT BY PRIOR amount = amount
AND PRIOR customer_number = customer_number
AND PRIOR next_groupid = groupid
GROUP BY amount, customer_number
which outputs:
AMOUNT | CUSTOMER_NUMBER | COUNT(*) :----- | --------------: | -------: 1000+ | 5555 | 3 2000+ | 6666 | 1
db<>fiddle here