0

カテゴリの階層をモデル化する一連のデータがあります。ルート カテゴリには、一連の最上位カテゴリが含まれます。各最上位カテゴリには、一連のサブカテゴリが含まれています。

各サブカテゴリには一連の組織があります。特定の組織が複数のサブカテゴリに表示される場合があります。

この階層のリーフ ノードは組織です。組織は、複数のサブカテゴリに表示される可能性があります。

データは、次の 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 をループして選択を実行し、そのカテゴリにマップされたすべての組織を取得します。各選択の結果は配列に追加されます。この配列には、組織が複数のサブカテゴリに表示されるたびに重複が含まれます。

このクラッジを、階層内のカテゴリの 1 つの ID を指定して個別の組織のリストを効率的に選択できるクエリに置き換えたいと思います。

PHPとMySQLを使用してこのソリューションを開発しています。

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

4

2 に答える 2

4

階層が常に正確に 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

これを 1 レベルずつ変更して、サブカテゴリ ID を渡すことができます。その時点で、カテゴリ 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

階層のレベル数が不明な場合 (または将来そうなる可能性があると思われる場合) は、Joe Celko の Trees and Hierarchies in SQL for Smartiesを参照して、階層をモデル化する別の方法を確認してください。とにかくそれをするのはおそらく良い考えです。

于 2008-12-18T17:52:06.747 に答える
0

データ モデルで許可されるかどうかはわかりませんが、単一のインデックス列とバイナリ ツリーを使用して、この情報を単一の「OrganizationTree」テーブルに簡単に格納できます。また、カテゴリ、サブカテゴリ、または組織レベルで検索するために、変更なしで単一のクエリを使用するという利点もあります (たとえば、X サブカテゴリのすべての結果を教えてください)。

お役に立てれば。

アダム。

于 2009-01-13T10:30:13.603 に答える