如何选择一个给定的节点下的SQL层级中的所有叶节点?
题
我有一组模型的类别的层次结构的数据。根类别包含一组顶层类别。每个顶层类别包含的一组子类别。
每个子类别具有一组的组织。一个组织可以出现在多个子类别。
此层次结构的叶节点是组织。一个组织可潜在地出现在多个子类别。
在数据被存储在三个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发民该溶液中。
感谢您的时间和建议。
解决方案
假设你的层次是总是精确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。如果你不知道你是否拥有一个类别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
如果您的层次结构可能有未知数量的水平(或者你认为它可能在未来),然后检查出的乔·塞科的树木和层次结构在SQL对替代方法的层次模型聪明豆。这可能是一个好主意,这样做呢。
其他提示
不知道你的数据模型将允许它,但你可以使用一个索引列和二叉树轻松此信息存储在一个单一的“OrganizationTree”表。也有您使用任何修改单个查询的类别,子类别,或组织水平,以搜索(例如给我X子类别的结果)
好处希望这有助于。
亚当。
不隶属于 StackOverflow