الحصول على بيانات شجرة القائمة ثابتة من جداول القائمة في MySQL

StackOverflow https://stackoverflow.com/questions/1465175

سؤال

لدي مشكلة شجرة / سلف / استعلام غير قادر على حلها:

لدي جدول بيانات قائمة عقد وطاولة تحتوي على جميع أسلاف القائمة:

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 والأخبار حتى أحصل على شجرة ثابتة. يجب أن تبدو هذه:

 +----+-----------+----------+
 | 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 |
+---------+--------------+------------+

تتيح لك إدخالات "الانعكاس" أن تنضم إلى مجموعة عناصر القائمة النشطة إلى جدول الإغلاق. يتيح لك تغيير المستوى إلى Pathlength لاستبعاد الإدخالات الانعكاسية من مجموعة الأجداد.

يمكنك الآن الاستعلام عن جميع عناصر القائمة التي هي أسلاف عناصر القائمة "النشطة"، بما في ذلك عناصر القائمة النشطة نفسها:

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