2017-11-13 7 views
2

임 사용자와 함께 가지고있는 계층 구조에 대한 성공적인 쿼리를 어떻게 얻을 수 있는지 궁금합니다. 비슷한 질문을 게시했지만 구조가 변경되어 이제 경영진 만 비용 할당자가 할당 될 수 있습니다.계층 구조 쿼리

  1. 이사
  2. 관리자
  3. 집행

예 테이블 USERS : 그들은 그들의 "의 costumers이있을 것이다

ID username privilege parent_ID 
1  Director1 1   null 
2  Director2 1   null 
3  Manager1 2   1 
4  Manager2 2   1 
5  Manager3 2   2 
6  Executive1 3   3 
7  Executive2 3   3 
8  Executive3 3   4 
9  Executive4 3   4 
10 Executive5 3   5 
11 Executive6 3   5 

그리고

사용자의 수준이 있습니다 ".

예 테이블의 costumers

내 문제는 내가 모든 사용자가 규칙이 될 것이라고, 그들은이 허용되는 단지의 costumers을 볼 수 있도록해야 어떤 종류의 결합에있다
ID name User_ID 
1 c1 11 
2 c2 10 
3 c3 10 
4 c4 9 
5 c5 8 
6 c6 7 
7 c7 6 

그들이 그 아래의 임원들 에게서만 의상을 볼 수 있으며 임원들은 자신의 의상을 볼 수 있습니다. 사용자가 자신의 costumers를 확인이라면

Diagram

상기 도면에 예를 들어 그 표시되어야

Director1 : C7, C6, C5, C4

Director2 : C3, C2를, C1

관리자 1 : C7, C6

Manager2 : C5, C4

,

관리자 3 : C3, C2, C1

경영진은 자신의 costumers를 볼 수 있습니다. https://dev.mysql.com/doc/refman/8.0/en/with.html

WITH RECURSIVE h AS (
    SELECT ID FROM USERS WHERE ID = ? 
    UNION 
    SELECT ID FROM USERS AS u JOIN h ON u.parent_ID = h.ID 
) 
SELECT c.* 
FROM h 
JOIN COSTUMERS AS c ON c.User_ID = h.ID; 

여전히 MySQL을 5.7 이상을 사용하는 경우, 당신은 어색 이상을 수행해야합니다

답변

2

이 문제를 해결하는 가장 적절한 방법은 MySQL의 8.0에서 오는 재귀 CTE 쿼리, 함께 . 하나의 장점이 있습니다. 즉, 계층 구조가 고정 된 최대 깊이를가집니다.

SELECT c.* 
FROM (
    SELECT e.ID FROM USERS AS e 
    WHERE e.ID = ? 
    UNION ALL 
    SELECT e.ID FROM USERS AS e 
    JOIN USERS AS m ON e.parent_ID = m.ID 
    WHERE m.ID = ? 
    UNION ALL 
    SELECT e.ID FROM USERS AS e 
    JOIN USERS AS m ON e.parent_ID = m.ID 
    JOIN USERS AS d ON m.parent_ID = d.ID 
    WHERE d.ID = ? 
) AS h 
JOIN COSTUMERS AS c ON c.User_ID = h.ID; 

클로저 테이블과 같은 다른 디자인으로 계층 구조를 재구성하는 것이 가능하지 않다고 가정합니다. 다른 디자인에 관심이 있다면 그러나, What is the most efficient/elegant way to parse a flat table into a tree?

에 대한 내 대답 또는 프레젠테이션 https://www.slideshare.net/billkarwin/models-for-hierarchical-data

또는 내 책 SQL Antipatterns: Avoiding the Pitfalls of Database Programming를 참조하십시오.

+0

감사합니다. MYSQL 8 사용에 대한 도움을 받으셨습니까? 이 dev에 버전을 사용해야합니까? 너무 많은 자원을 소비하는 버전 5.7이기 때문에 그것을 사용하거나 8.0을 기다리는 데 좋은 아이디어 일 수 있습니까? –

+0

또한 프레젠테이션을 읽는 중, 모든 데이터베이스를 구조화하는 단계에 있기 때문에 상황을 바꿀 수있는 범위를 벗어난 것이 아니므로 변경 사항을 적용 할 수 있습니다. 테이블을 더 잘 닫을 수 있을까요? –

+0

MySQL 8.0은 현재 아직 릴리스 후보 상태입니다. 프로덕션 환경에서 사용할 준비가되었는지 알기에는 너무 이르므로 신중하게 테스트해야합니다. MySQL 커뮤니티에는 ".20"릴리스 (예 : MySQL 8.0.20)에 도달 할 때까지 새로운 주요 버전을 채택하지 않도록하는 농담이 있습니다. 그런 다음 주요 버그와 거친 비트가 해결되어야합니다. 이 규칙은 전 MySQL 개발 이사 (https://www.flamingspork.com/blog/2013/08/01/stewarts-dot-twenty-rule/ –