주어진 노드에서 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를 통해 코드의 각 범주를 통해 루핑하고 모든 조직이 해당 범주에 매핑되도록 선택을 수행하는 것과 관련이 있습니다. 각 선택의 결과는 배열에 추가됩니다. 이 배열에는 조직이 여러 하위 범주에 나타날 때마다 중복이 포함되어 있습니다.

이 kludge를 계층 구조에서 범주 중 하나의 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

계층이 알려지지 않은 수준의 레벨을 가질 수 있다면 (또는 미래에도 생각할 수도 있음) Joe Celko의 나무와 Smlies for Smarties의 Trees and Hierrarchies 계층 구조를 모델링하는 대안적인 방법. 어쨌든 그렇게하는 것이 좋은 생각 일 것입니다.

다른 팁

데이터 모델이 허용되는지 확실하지 않지만 단일 인덱스 열과 이진 트리를 사용 하여이 정보를 단일 '조직 트리'테이블에 쉽게 저장할 수 있습니다. 또한 카테고리, 하위 범주 또는 조직 레벨에서 검색하기 위해 수정없이 단일 쿼리를 사용하는 이점이 있습니다 (예 : X 하위 범주의 모든 결과를 제공 함).

도움이 되었기를 바랍니다.

아담.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top