8. ①関連性を洗い出す。一つ先まで
・処理をする上で、ColA⇒ColB、ColB⇒ColAといった判断を
行うことが面倒です。
・全てのケースを洗い出し、ColA⇒ColBの処理で完結するように
「main」共通テーブルを作成します。
・関連性はColA⇒ColBだけでなく、その一つ先まで加味します。
RELATION
ColA ColB
A B
B C
C D
E F
A G
B H
N F
RELATION 逆
ColA ColB
B A
C B
D C
F E
G A
H B
F N
with
main as (
select * from RELATION
union
select ColB,ColA from RELATION as A
union
select A.ColA,B.ColB from RELATION as A
inner join RELATION as B on A.ColB = B.ColA
union
select A.ColA,B.ColA from RELATION as A
inner join RELATION as B on A.ColA = B.ColB
union
select A.ColA,B.ColA from RELATION as A
inner join RELATION as B on A.ColB = B.ColB
union
select A.ColB,B.ColB from RELATION as A
inner join RELATION as B on A.ColB = B.ColA
union
select A.ColB,B.ColA from RELATION as A
inner join RELATION as B on A.ColA = B.ColB
union
select A.ColA,B.ColA from RELATION as A
inner join RELATION as B on A.ColB = B.ColB
)
9. ColAから見た一つ先(ColB)ColBとColA結合
ColA ColB ColA ColB ColA ColB
A B B C A C
結合 B H 結果 A H
B C C D B D
C D
E F
A G
B H
N F
ColAから見た一つ先(ColA)ColAとColB結合
ColA ColB ColA ColB ColA ColB
A B
B C 結合 A B 結果 B A
C D B C C B
E F
A G
B H A B B A
N F
①関連性を洗い出す。一つ先まで
ColAから見た一つ先(ColA)ColBとColB結合
ColA ColB ColA ColB ColA ColB
A B A B A A
B C 結合 B C 結果 B B
C D C D C C
E F E F E E
N F E N
A G A G A A
B H B H B B
N F E F N E
N F N N
10. ColBから見た一つ先(ColB)ColBとColA結合
ColA ColB ColA ColB ColA ColB
A B B C B C
結合 B H 結果 B H
B C C D C D
C D
E F
A G
B H
N F
ColBから見た一つ先(ColA)ColAとColB結合
ColA ColB ColA ColB ColA ColB
A B
B C 結合 A B 結果 C A
C D B C D B
E F
A G
B H A B H A
N F
①関連性を洗い出す。一つ先まで
ColBから見た一つ先(ColA)ColBとColB結合
ColA ColB ColA ColB ColA ColB
A B A B B A
B C 結合 B C 結果 C B
C D C D D C
E F E F F E
N F F N
A G A G G A
B H B H H B
N F E F F E
N F F N
13. ColA ColB
A A
A B
A C
A G
A H
B A
B B
B C
B D
B H
C A
C B
C C
C D
D B
D C
E E
E F
E N
F E
F N
G A
H A
H B
N E
N F
N N
②関連するデータをまとめて、連番を付番
・ColAに属するColBのデータをString_aggでまとめて一つにします。
Col SortKey
A ABCGH
B ABCDH
C ABCD
D BC
E EFN
F EN
G A
H AB
N EFN
14. ②関連するデータをまとめて、連番を付番
Col SortKey
A ABCGH
B ABCDH
C ABCD
G A
H AB
D BC
E EFN
F EN
N EFN
・SortKey基の最初の1文字とColAの昇順で連番を振ります。(以降no)
・SortKeyは関連性の近いグループの集まりになります。
また集まりを使用して昇順に連番を振ることで、
SortKeyのグループの中で上から順番に若いアルファベットに
なります。
no Col SortKey
1 A ABCGH
2 B ABCDH
3 C ABCD
4 G A
5 H AB
6 D BC
7 E EFN
8 F EN
9 N EFN
Aが属するグループ
Bが属するグループ
Eが属するグループ
各グループの昇順に付番
15. Col SortKey
A ABCGH
B ABCDH
C ABCD
G A
H AB
D BC
E EFN
F EN
N EFN
②関連するデータをまとめて、連番を付番
・SortKeyの一桁を使って連番を振るのは、今回はグループ内の昇順としたいのですが、
データの関連性の仕方によって、グループ内の順番がずれてしまうケースがあるためです。
この場合、次の処理でNGになります。
no Col SortKey
1 G A
2 H AB
3 C ABCD
4 B ABCDH
5 A ABCGH
6 D BC
7 E EFN
8 N EFN
9 F EN
Aが属するグループ
Bが属するグループ
Eが属するグループ
全ての桁で付番号
グループごとの
Colの昇順に
なってない!
17. ・自分の上にあるデータのSortKeyに自分のColが含まれるデータがない場合は、0(開始)
・含まれるデータがある場合は、1(2番以降)を付番
no Col SortKey
1 A ABCGH
Aの場合、自分より上にデータがないので0(開始)
no Col SortKey
2 B ABCDH
Bの場合、自分より上にAデータがあり、AのSortKeyにBが含まれるので1(2番目以降)
no Col SortKey
6 D BC
no Col SortKey
1 A ABCGH
Dまで同じ1(2番目以降)
no Col SortKey
1 A ABCGH
2 B ABCDH
3 C ABCD
4 G A
5 H AB
③グループの開始のデータとそれ以外を分ける
no Col SortKey
1 A ABCGH
2 B ABCDH
3 C ABCD
4 G A
5 H AB
6 D BC
7 E EFN
8 F EN
9 N EFN
19. ・区分けしたら、開始と2番目以降のグループに分けてnoの昇順で再付番します。
no Col SortKey chk
1 A ABCGH 0
2 B ABCDH 1
3 C ABCD 1
4 G A 1
5 H AB 1
6 D BC 1
7 E EFN 0
8 F EN 1
9 N EFN 1
Chk列に0or1を追加
再付番
no Col SortKey chk
1 A ABCGH 0
2 E EFN 0
1 B ABCDH 1
2 C ABCD 1
3 G A 1
4 H AB 1
5 D BC 1
6 F EN 1
7 N EFN 1
③グループの開始のデータとそれ以外を分ける
20. ④グループの開始とそれ以外を再帰で比較、結合していく。
,fin (Grp_no,Col,Sortkey,Row_no) as (
select
anc.no
,anc.Col
,anc.Sortkey
,0
from
sub2 as anc
where
anc.chk = 0
union all
select
fin.Grp_no
,case when fin.Sortkey like '%'+ Rec.Col + '%' then Rec.Col else fin.Col end
,fin.Sortkey + case when fin.Sortkey like '%'+ Rec.Col + '%' then Rec.Sortkey else '' end
,fin.Row_no + 1
from
fin
inner join
sub2 as Rec
on (fin.Row_no + 1 = Rec.no and Rec.chk = 1)
)
22. ④グループの開始とそれ以外を再帰で比較、結合していく。
Group_No Col SortKey Row_No
1 A ABCGH 0 + 1(結合時)
2 E EFN 0 + 1
1回目 Row_No + 1 とnoを結合
Col=Bは、Row_No=0のSortKeyに含まれる
no Col SortKey chk
1 B ABCDH 1
Group_No Col SortKey Row_No
1 B ABCGHABCDH 1
2 E EFN 1
作成データ
Group_No=1のSortkeyを結合
1回目終了時のテーブル(アンカー+1回目データのUnion all)
Group_No Col SortKey Row_No
1 A ABCGH 0
1 B ABCGHABCDH 1
2 E EFN 0
2 E EFN 1
23. ④グループの開始とそれ以外を再帰で比較、結合していく。
Group_No Col SortKey Row_No
1 B ABCGHABCDH 1 + 1(結合時)
2 E EFN 1 + 1
2回目 Row_No + 1 とnoを結合
Col=Bは、Row_no=1のSortKeyに含まれる
no Col SortKey chk
2 C ABCD 1
Group_No Col SortKey Row_No
1 C ABCGHABCDHABCD 1
2 E EFN 1
2回目終了時のテーブル(2回目データのUnion all)
Group_No Col SortKey Row_No
1 A ABCGH 0
1 B ABCGHABCDH 1
1 C ABCGHABCDHABCD 2
2 E EFN 0
2 E EFN 1
2 E EFN 2
・左記の様に、関連するデータについては、
次の情報が更新され、関連しない場合は、
前回の情報が引き継がれるため、次も同じ
条件で比較できる。
・自分より上にデータが存在するかというやり方も
可能だが、再帰の回数にしたがってデータが反比例に
増えていくので激重になります。
作成データ
Group_No=1のSortkeyを結合
24. ④グループの開始とそれ以外を再帰で比較、結合していく。
3から飛ばして6回目 Row_No + 1 とnoを結合
Col=Fは、Row_no=5のSortKeyに含まれる
Grp_no Col Sortkey Row_no
1D ABCGHABCDHABCDAABBC 5 + 1 (結合時)
2E EFN 5 + 1 (結合時)
no Col SortKey chk
6 F EN 1
Group_No Col SortKey Row_No
1 D ABCGHABCDHABCDAABBC 1
2 F EFNEN 1
6回目で二つ目のグループの処理が始まる。
終了時のテーブル(6回目データのUnion all)
Grp_no Col Sortkey Row_no
1 A ABCGH 0
1 B ABCGHABCDH 1
1 C ABCGHABCDHABCD 2
1 G ABCGHABCDHABCDA 3
1 H ABCGHABCDHABCDAAB 4
1 D ABCGHABCDHABCDAABBC 5
1 D ABCGHABCDHABCDAABBC 6
2 E EFN 0
2 E EFN 1
2 E EFN 2
2 E EFN 3
2 E EFN 4
2 E EFN 5
2 F EFNEN 6
作成データ
Group_No=2のSortkeyを結合
25. ④グループの開始とそれ以外を再帰で比較、結合していく。
最後の処理が終わった状態
Grp_no Col Sortkey Row_no
1A ABCGH 0
1B ABCGHABCDH 1
1C ABCGHABCDHABCD 2
1G ABCGHABCDHABCDA 3
1H ABCGHABCDHABCDAAB 4
1D ABCGHABCDHABCDAABBC 5
1D ABCGHABCDHABCDAABBC 6
1D ABCGHABCDHABCDAABBC 7
2E EFN 0
2E EFN 1
2E EFN 2
2E EFN 3
2E EFN 4
2E EFN 5
2F EFNEN 6
2N EFNENEFN 7
26. ⑤Group_noとColで重複除外し、並べ替える。
select
distinct Grp_no,Col
from fin
order by Grp_no,Col
Grp_no Col Sortkey Row_no
1 A ABCGH 0
1 B ABCGHABCDH 1
1 C ABCGHABCDHABCD 2
1 G ABCGHABCDHABCDA 3
1 H ABCGHABCDHABCDAAB 4
1 D ABCGHABCDHABCDAABBC 5
1 D ABCGHABCDHABCDAABBC 6
1 D ABCGHABCDHABCDAABBC 7
2 E EFN 0
2 E EFN 1
2 E EFN 2
2 E EFN 3
2 E EFN 4
2 E EFN 5
2 F EFNEN 6
2 N EFNENEFN 7
Grp_no Col
1 A
1 B
1 C
1 D
1 G
1 H
2 E
2 F
2 N
完成!