I don't understand why you exclude 1002 from your duplicate list? 1002 has the same values for bu, pr and ac as 1001, 1003 & 1005? Same for 1004.
Is the rule really:
- Find all the PI values that appear more than once
- For each of these, find any other duplicated PI values which have the same value for BU, PR & AC?
If so, you can do this with a single pass through the table. Use count(*) over() in a subquery to find the duplicated PIs. Then group the results of this to get the matching other rows:
with dup_pis as (
select t.*, count(*) over ( partition by pi ) ct from t
)
select bu, pr, ac,
listagg(pi, ',') within group (order by pi) pis
from dup_pis
where ct > 1
group by bu, pr, ac
having count(*) > 1;
BU PR AC PIS
100 PR1 AC1 1001,1003,1005
100 PR1 AC2 1001,1003,1005
This is a single pass through the table (instead of 4). So I'd expect this to be notably faster.
If you need the results as separate rows, use your favourite "csv to rows" method. You can find some at:
https://asktom.oracle.com/pls/apex/f?p=100:11:0::::P11_QUESTION_ID:9526081800346942316