3つの関連テーブルがあります。Parts、PartGroup、MarkupGroupです。
パーツはシンプルです。
PartID artificial primary key
Part part number
PartGroupID Foreign key
サンプルデータ:
1 T1000 5
2 wizbang gold 17
3 flux capacitor 2
PartGroupは、自己リンクされた親キーでモデル化された非循環有向グラフ(ツリー)です
PartGroupID artificial primary key
Description name of group
ParentID foreign key linked to PartGroupID
MarkupGroupID foreign key linked to MarkupGroup
サンプルデータは次のようになります。
1 system null null
2 component null 1
3 software null 2
4 abc 1 3
5 xyz 1 4
6 123 4 null
7 456 4 null
8 789 5 null
9 a1 6 null
10 b2 6 null
11 c3 7 null
12 d4 7 null
13 e5 8 null
14 f6 8 null
15 alpha 3 null
16 beta 3 null
17 gamma 3 null
MarkupGroupは、マークアップ係数をセットとして複数のPartGroupに適用します。
MarkupGroupID primary key
MarkupFactor numeric attribute field
サンプルデータ-
1 15
2 20
3 25
4 22
パーツテーブルの各パーツに適切なマークアップ金額を返すクエリを作成する必要があります。複数のマークアップを1つのパーツに適用できる場合はありません。マークアップを見つけるにはグラフを再帰的に調べる必要がありますが、クエリの時点では、null以外のマークアップを見つけるために再帰が必要なレベルの数がわかりません。
ツリーの途中で、パーツがマージンへの可能な複数の結合に遭遇することは決してないので、実行する必要のある累積はありません。
T1000のタイプはxyzで、MarginGroupへの外部キーがあるため、結合して値を取得できます。親も持っていますが、必要な値があるのでそれは関係ありません。
Wizbang Goldはガンマグループソフトウェアであり、外部キーはありませんが、親ノードの「ソフトウェア」が実行するので、それを返す必要があります。
フラックスコンデンサはコンポーネントであり、MarginGroupへの直接外部キーを持っています。その値を返します。
したがって、結果は次のようになります。
1 T1000 22
2 wizbang gold 20
3 flux capacitor 15
これを実現するには、再帰的なCTEとAPPLYのフレーバーが必要になると確信していますが、現時点では私の脳はうまく機能していません。ミドルテーブルの再帰的な性質がなければ、これは非常に簡単です。プラットフォームはMS-SQLです。
あなたはCTEでMarkupGroupID
を持ってトップダウンで再帰を行うことができます。
with C as
(
select P.PartGroupID,
P.ParentID,
P.MarkupGroupID
from PartGroup as P
where P.ParentID is null
union all
select P.PartGroupID,
P.ParentID,
coalesce(P.MarkupGroupID, C.MarkupGroupID)
from PartGroup as P
inner join C
on P.ParentID = C.PartGroupID
)
select P.PartID,
P.Part,
MG.MarkupFactor
from Parts as P
inner join C
on P.PartGroupID = C.PartGroupID
inner join MarkupGroup as MG
on C.MarkupGroupID = MG.MarkupGroupID
order by P.PartID
再帰CTEは、次のような派生テーブルを作成します。
PartGroupID ParentID MarkupGroupID
----------- ----------- -------------
1 NULL NULL
2 NULL 1
3 NULL 2
15 3 2
16 3 2
17 3 2
4 1 3
5 1 4
8 5 4
13 8 4
14 8 4
6 4 3
7 4 3
11 7 3
12 7 3
9 6 3
10 6 3
マークアップに接続されていないパーツグループのパーツが必要な場合は、メインクエリでMarkupGroup
に対して外部結合を使用できます。
with C as
(
select ...
)
select P.PartID,
P.Part,
MG.MarkupFactor
from Parts as P
inner join C
on P.PartGroupID = C.PartGroupID
left outer join MarkupGroup as MG
on C.MarkupGroupID = MG.MarkupGroupID
order by P.PartID