需求:
课程表:tb_Course
| 
 CID  | 
 CN(Course Name)  | 
| 
 1  | 
 C1  | 
| 
 2  | 
 C2  | 
区域国家表: tb_Area
| 
 AID  | 
 AN(Area Name)  | 
 CoID (Country ID)  | 
| 
 1  | 
 A1  | 
 1  | 
| 
 1  | 
 A1  | 
 …  | 
| 
 1  | 
 A1  | 
 n  | 
| 
 2  | 
 A2  | 
 n+1  | 
| 
 2  | 
 A2  | 
 …  | 
| 
 2  | 
 A2  | 
 2n  | 
| 
 3  | 
 A3  | 
 2n+1  | 
| 
 3  | 
 A3  | 
 …  | 
| 
 3  | 
 A3  | 
 3n  | 
课程到国家的同步状态 tb_record
| 
 CID(Course ID)  | 
 CoID(Country ID)  | 
 status  | 
 | 
| 
 | 
 | 
 0,1,2  | 
 | 
展示样例:
| 
 CID  | 
 DistributeArea (include tb_record.status is 2)  | 
 No_DistributeArea (include tb_record.status is 0, 1)  | 
| 
 1  | 
 A1(2);A2(2)  | 
 A3(1)  | 
| 
 2  | 
 A3(2)  | 
 A1(0);A2(1)  | 
实现:
第一步:先关联 tb_Area 和 tb_record 得到区域的同步状态AS以及区域分发状态AD:
Select tbR.CID, tbA.AN decode(min(tbR.status), ‘0’, ‘0’, ‘1’, ‘1’, ‘2’) AS, decode(min(tbR.status), ‘2’, ‘1’, ‘0’) AD
From tb_Area tbA left join tb_record tbR on tbA.CoID = tbR.CoID
Group by tbR.CID, tbA.AN 结果表:T1
| 
 CID  | 
 AN  | 
 AS  | 
 AD  | 
| 
 1  | 
 A1  | 
 2  | 
 1  | 
| 
 1  | 
 A2  | 
 2  | 
 1  | 
| 
 1  | 
 A3  | 
 1  | 
 0  | 
| 
 2  | 
 A1  | 
 0  | 
 0  | 
| 
 2  | 
 A2  | 
 1  | 
 0  | 
| 
 2  | 
 A3  | 
 2  | 
 1  | 
第二步:思路是先构建一颗树,然后再将树转成列:
方法1:构建树,先设法构建父子关系表 T2
1、先给表排序获得行号作为父节点ID
Select T1.CID, T1.AN, T1.AS, T1.AD, rownum over(order by T1.CID,T1.AD) rnFirst
From T1 得到T2
| 
 CID  | 
 AN  | 
 AS  | 
 AD  | 
 rnFirst  | 
| 
 1  | 
 A1  | 
 2  | 
 1  | 
 1  | 
| 
 1  | 
 A2  | 
 2  | 
 1  | 
 2  | 
| 
 1  | 
 A3  | 
 1  | 
 0  | 
 3  | 
| 
 2  | 
 A1  | 
 0  | 
 0  | 
 4  | 
| 
 2  | 
 A2  | 
 1  | 
 0  | 
 5  | 
| 
 2  | 
 A3  | 
 2  | 
 1  | 
 6  | 
2、使用lead函数和分区特性得到子节点id
Select T2.CID, T2.AN, T2.AS, T2.AD, T2.rnFirst, lead(T2.rnFirst) over(partition by T2.CID,T2.AD order by T2.rnFirst) rnNext From T2 得到T3
| 
 CID  | 
 AS  | 
 AD  | 
 rnFirst  | 
 rnNext  | 
| 
 1  | 
 2  | 
 1  | 
 1  | 
 2  | 
| 
 1  | 
 2  | 
 1  | 
 2  | 
 Null  | 
| 
 1  | 
 1  | 
 0  | 
 3  | 
 Null  | 
| 
 2  | 
 0  | 
 0  | 
 4  | 
 5  | 
| 
 2  | 
 1  | 
 0  | 
 5  | 
 Null  | 
| 
 2  | 
 2  | 
 1  | 
 6  | 
 Null  | 
3、构造树,利用sys_connect_by_path函数链接字符串
Select T3.CID, T3.AD, sys_connect_by_path(T3.AN ||’(‘ || T3.AS || ‘)’,,) Area
From T3
Start with T3.rnNext is Null
Connect by rnNext = prior rnFirst 得到T4
| 
 CID  | 
 AD  | 
 Area  | 
| 
 1  | 
 1  | 
 ,A1(2)  | 
| 
 1  | 
 1  | 
 ,A1(2),A2(2)  | 
| 
 1  | 
 0  | 
 ,A3(1)  | 
| 
 2  | 
 0  | 
 ,A1(0)  | 
| 
 2  | 
 0  | 
 ,A1(0),A2(1)  | 
| 
 2  | 
 1  | 
 ,A3(2)  | 
合成一个语句:
Select T3.CID, T3.AD, sys_connect_by_path(T3.AN ||’(‘ || T3.AS || ‘)’,,) Area
From (Select T2.CID, T2.AN, T2.AS, T2.AD, T2.rnFirst, lead(T2.rnFirst) over(partition by T2.CID,T2.AD order by T2.rnFirst) rnNext 
From (Select T1.CID, T1.AN, T1.AS, T1.AD, rownum over(order by T1.CID,T1.AD) rnFirst
From T1
     ) T2
) T3
Start with T3.rnNext is Null
Connect by rnNext = prior rnFirst
方法二:10G 中的wmsys.wm_concat 方法
Select T1.CID, T1.Ad, wmsys.wm_concat(T3.AN ||’(‘ || T3.AS || ‘)’) over(partition by T1.CID, T1.AD order by rownum) Area
From T1
第三步、分组取最大值:
Select T4.CID, T4.AD, ltrim(max(t4.Arear),,) Area From T4 得到T5
| 
 CID  | 
 AD  | 
 Aarer  | 
| 
 1  | 
 1  | 
 A1(2),A2(2)  | 
| 
 1  | 
 0  | 
 A3(1)  | 
| 
 2  | 
 0  | 
 A1(0),A2(1)  | 
| 
 2  | 
 1  | 
 A3(2)  | 
第四步:行转列
Select T5.CID, max(decode(T5.AD, ‘1’, T5.Area, ‘’)) v1, max(decode(T5.AD, ‘0’, T5.Area, ‘’)) v2
From T5
Group by T5.CID
| 
 CID  | 
 V1  | 
 V2  | 
| 
 1  | 
 A1(2),A2(2)  | 
 A3(1)  | 
| 
 2  | 
 A3(2)  | 
 A1(0),A2(1)  | 
                    
                
                
            
        
浙公网安备 33010602011771号