在Oracle SQL中对记录对进行分组

时间:2016-03-14 00:35:50

标签: sql oracle

我有一个客户匹配表,其中包含一对客户ID,如下所示。

PAIR_ID     CUST_ID MATCH_CUST_ID
12345       800001  900001
12346       800002  900001
12347       800003  900001
12348       800004  900002
12349       900003  900004
12350       900004  900005
12351       900004  900006

我想创建单独的组,其中包含链接的所有客户ID。

例如,

第1组:

800001
800002
800003
900001

第2组:

800004
900002

第3组:

900003
900004
900005
900006

是否有一种简单的方法可以确保我不会错过应该包含在群组中的任何一对?

2 个答案:

答案 0 :(得分:1)

打击应该成功:

with cpair (PAIR_ID, CUST_ID, MATCH_CUST_ID) 
as 
(select 12345, 800001, 900001 from dual
 union all 
 select 12346, 800002, 900001 from dual
 union all 
 select 12347, 800003, 900001 from dual
 union all 
 select 12348, 800004, 900002 from dual
 union all 
 select 12349, 900003, 900004 from dual
 union all 
 select 12350, 900004, 900005 from dual
  union all 
 select 12351, 900004, 900006 from dual) ,  
tree  (mainid, custid, matchcustid, path) as 
( select cust_id, cust_id, match_cust_id, to_char(pair_id) 
from cpair
union all
select mainid,
    case when ( p.CUST_ID = t.matchcustid )  then p.CUST_ID
         when ( p.MATCH_CUST_ID = t.matchcustid )  then p.match_CUST_ID
         when (  p.cust_id = t.custid )  then p.CUST_ID
         when ( p.match_cust_id = t.custid )  then p.match_CUST_ID   
    end,
    case when ( p.CUST_ID = t.matchcustid )  then p.MATCH_CUST_ID
         when ( p.MATCH_CUST_ID = t.matchcustid )  then p.CUST_ID
         when (  p.cust_id = t.custid )  then p.MATCH_CUST_ID
         when ( p.match_cust_id = t.custid )  then p.CUST_ID   
    end, 
    t.path || '-' || to_char(p.PAIR_ID) 
from tree t
join cpair p
on 
 ( p.CUST_ID = t.matchcustid 
 or p.MATCH_CUST_ID = t.matchcustid 
 or p.cust_id = t.custid 
 or p.match_cust_id = t.custid 
 ) 
 and instr(path, pair_id ) < 1   
  ),
distinctTree as 
(
  select distinct mainid, matchcustid
   from tree
  union all 
   select distinct mainid, mainid 
   from tree
  order by mainid ),
treeGroup as (
  select mainid, listagg(matchcustid, ',') within group (order by matchcustid) custList 
  from distinctTree
  group by mainid )
  select distinct custlist from treeGroup 

结果:

CustList
-------------
800004,900002
900003,900004,900005,900006
800001,800002,800003,900001

查询以递归方式通过客户关系树进行,并为每个客户创建相关客户列表。之后,相关客户列表将更改为用于分组的字符串。从分组我们可以看到客户属于哪个组。

答案 1 :(得分:0)

with T0 as (--input data
select 12345 as pair_id,800001 as cust_id,900001 as mutch_cust_id from dual
union all
select 12346,       800002,  900001 from dual
union all
select 12347,       800003,  900001 from dual
union all
select 12348,       800004,  900002 from dual
union all
select 12349 ,      900003,  900004 from dual
union all
select 12350,       900004,  900005 from dual
union all 
select 12351,       900004,  900006 from dual

),
T1 as (--input data + mirror
select pair_id, cust_id, mutch_cust_id, 'input' as sign from t0
union all
select pair_id, mutch_cust_id, cust_id, 'mirror' from t0
)
--result 
select  max(CONNECT_BY_ROOT x.pair_id) "group", x.cust_id
from T1 x
start with x.sign='input'
connect by nocycle prior x.cust_id=x.mutch_cust_id 
group by x.cust_id
order by 1,2