문제

해결할 수 없는 트리/조상/쿼리 문제가 있습니다.

메뉴 데이터가 포함된 테이블과 메뉴의 모든 상위 항목이 포함된 테이블이 있습니다.

table menu               table ancestors
+-----+------------+--------+     +---------+--------------+-------+
| id  |      title | active |     | menu_id |  ancestor_id | level |
+-----+------------+--------+     +---------+--------------+-------+
|   1 |       Home |      0 |     |       1 |            0 |     0 |
|   2 |       News |      0 |     |       2 |            1 |     1 |
|   3 |        Foo |      0 |     |       3 |            2 |     2 |
|   4 |        Bar |      1 |     |       3 |            1 |     1 |
|   5 |  Downloads |      1 |     |       4 |            3 |     3 |
+-----+------------+--------+     |       4 |            2 |     2 |
                                  |       4 |            1 |     1 |
                                  |       5 |            1 |     1 |
                                  +---------+--------------+-------+

다음을 사용하여 조상과 함께 모든 활성 메뉴 항목을 쉽게 얻을 수 있습니다.

 SELECT menu.id, menu.title, GROUP_CONCAT(ancestors.ancestor_id) as ancestors
FROM menu, ancestors
WHERE menu.active = 1
GROUP BY (menu.id);

 +----+-----------+----------+
 | id |     title |ancestors |
 +----+-----------+----------+
 |  4 |       Bar | 3,2,1    | 
 |  5 | Downloads | 1        |
 +----+-----------+----------+

그런데 나무에 필요한 조상을 어떻게 모두 얻을 수 있습니까?결과적으로 일관된 트리를 얻으려면 Foo 및 News 항목이 필요합니다.다음과 같아야 합니다.

 +----+-----------+----------+
 | id |     title |ancestors |
 +----+-----------+----------+
 |  2 |      News | 1        | 
 |  3 |       Foo | 2,1      | 
 |  4 |       Bar | 3,2,1    | 
 |  5 | Downloads | 1        |
 +----+-----------+----------+

쿼리는 어떻게 되나요?

도움이 되었습니까?

해결책

내가 이것을 할 때, 나는 구조를 구성한다. ancestors 테이블이 조금 다릅니다.대신에 level, 나는 저장한다 pathlength.또한 경로 길이가 0인 각 메뉴 항목이 자신을 가리키도록 행을 저장합니다.

+---------+--------------+------------+
| menu_id |  ancestor_id | pathlength |
+---------+--------------+------------+
|       1 |            1 |          0 |
|       2 |            2 |          0 |
|       3 |            3 |          0 |
|       4 |            4 |          0 |
|       5 |            5 |          0 |
|       2 |            1 |          1 |
|       3 |            2 |          2 |
|       3 |            1 |          1 |
|       4 |            3 |          3 |
|       4 |            2 |          2 |
|       4 |            1 |          1 |
|       5 |            1 |          1 |
+---------+--------------+------------+

이러한 "반사" 항목을 사용하면 활성 메뉴 항목 세트를 클로저 테이블에 결합할 수 있습니다.레벨을 경로 길이로 변경하면 조상 세트에서 반사 항목을 제외할 수 있습니다.

이제 활성 메뉴 항목 자체를 포함하여 "활성" 메뉴 항목의 조상인 모든 메뉴 항목을 쿼리할 수 있습니다.

SELECT a2.menu_id, m2.title, GROUP_CONCAT(a2.ancestor_id) AS ancestors
FROM menu m1
JOIN ancestors a1 ON (m1.id = a1.menu_id)
JOIN ancestors a2 ON (a1.ancestor_id = a2.menu_id AND a2.pathlength > 0)
JOIN menu m2 ON (a2.menu_id = m2.id)
WHERE m1.active = 1
GROUP BY a2.menu_id;

결과:

+---------+-----------+-----------+
| menu_id | title     | ancestors |
+---------+-----------+-----------+
|       2 | News      | 1         | 
|       3 | Foo       | 2,1       | 
|       4 | Bar       | 3,2,1     | 
|       5 | Downloads | 1         | 
+---------+-----------+-----------+
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top