どのように私は与えられたノードの下にSQL階層内のすべてのリーフノードを選択することができますか?

StackOverflow https://stackoverflow.com/questions/378608

  •  22-08-2019
  •  | 
  •  

質問

私は、データモデルカテゴリの階層のセットを持っています。ルートカテゴリは、トップレベルカテゴリのセットが含まれています。各トップレベルのカテゴリは、サブカテゴリのセットが含まれています。

各サブカテゴリーは、組織のセットを持っています。与えられた組織は、複数のサブカテゴリーに表示されます。

この階層のリーフノードは、組織されています。組織は、潜在的に複数のサブカテゴリーに表示されることがあります。

データは3つのSQLテーブルに格納されます:

organizations
organization_id organization_name
1               Org A
2               Org B
3               Org C
4               Org D
5               Org E
6               Org F

categories
category_id parent_id category_name
0           NULL      Top Level Category
1           0         First Category
2           0         Second Category
3           1         Sub Category A
4           1         Sub Category B
5           1         Sub Category C
6           2         Sub Category D

organizations_categories -- Maps organizations to sub_categories
organization_id category_id
1               3
2               3
2               6
3               4
4               4
5               4
6               5
6               4
7               6
8               6

私は、与えられたカテゴリまたはサブカテゴリの下にあるすべてのユニークな組織のリストを選択できるようにしたいと思います。

私は今それをやっている方法は、サブカテゴリーが要求されている最初把握し、コード内の各sub_categoryをループして、そのカテゴリにマッピングされたすべての組織を得るために選択が実施されます。各選択の結果は、アレイに追加されます。組織が複数のサブカテゴリーに表示されたときにこの配列には重複が含まれています。

私は効率的、階層内のカテゴリのいずれかのIDを与えられた明確な組織のリストを選択することができ、クエリで、この場しのぎを交換したいと思います。

私は、PHPとMySQLを使用して、このソリューションをdevlopingています。

あなたの時間と提案をいただきありがとうございます。

役に立ちましたか?

解決

あなたの階層が常に正確に3つのレベルの深さであると仮定すると、

SELECT DISTINCT
     O.organization_id,
     O.organization_name
FROM
     Categories CAT
INNER JOIN Categories SUB ON
     SUB.parent_id = CAT.category_id
INNER JOIN Category_Organizations CO ON
     CO.category_id = SUB.category_id
INNER JOIN Organizations O ON
     O.organization_id = CO.organization_id
WHERE
     CAT.category_id = @category_id

あなたは、サブカテゴリIDを渡すことができるようにする1つのレベルでそれを変更することができます。あなたは、カテゴリIDまたはサブカテゴリIDを持っているか否かの時点でわからない場合、あなたは次の操作を行うことができます:

SELECT DISTINCT
     O.organization_id,
     O.organization_name
FROM
     Categories CAT
LEFT OUTER JOIN Categories SUB ON
     SUB.parent_id = CAT.category_id
INNER JOIN Category_Organizations CO ON
     CO.category_id IN (CAT.category_id, SUB.category_id)
INNER JOIN Organizations O ON
     O.organization_id = CO.organization_id
WHERE
     CAT.category_id = @category_id

あなたの階層がレベルの未知の数を有することができる(またはあなたはそれが将来的にかもしれないと思う)をチェックしてください<のhref =「https://rads.stackoverflow.com/amzn/click/com/1558609202」のrel場合=「nofollowをnoreferrer」>階層をモデル化するための別の方法のためのスマーティーズのためのSQLでのジョー・セルコの木と階層。これはおそらく、とにかくそれを行うことをお勧めします。

他のヒント

あなたのデータモデルは、それができるようになりますが、あなたは簡単にシングル「OrganizationTree」テーブルにこの情報を格納するために、単一のインデックス列とバイナリツリーを使用できるかどうかわかりません。また、あなたが(例えば私のXのサブカテゴリのすべての結果を与える)

カテゴリ、サブカテゴリ、または組織レベルで検索するように変更なしで単一のクエリを使用する利点を持っています

この情報がお役に立てば幸いです。

アダムます。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top