sql >> Database >  >> RDS >> Mysql

MySQL Tree gerangschikt op ouder en kind

Er zijn andere manieren om hiërarchische gegevens te ordenen naast de methoden die worden getoond in de blog van Mike Hillyer. Ik gebruik graag een methode die ik transitieve afsluittabel noem of kortweg sluittafel. In dit ontwerp slaat u elk pad door de hiërarchie op, als voorouder/nakomeling-paren.

create table closure (
    ancestor int,
    descendant int,
    length int,
    primary key (ancestor,descendant),
    key (descendant,ancestor)
);
insert into closure values
(1,1,0),
(1,3,1),
(1,4,2),
(1,5,3),
(2,2,0),
(3,3,0),
(3,4,1),
(3,5,2),
(4,4,0),
(4,5,1),
(5,5,0);

Merk op dat deze set zelfs de "paden" met lengte nul bevat, d.w.z. een menu-item is een "ouder" van zichzelf.

Nu kunt u deelnemen aan elk menu-item m aan al zijn voorouders a , door lid te worden van paden waar m is de sollicitant. Ga vanaf daar terug naar het menu-item o die zich in de set van voorouders bevindt, en je hebt toegang tot de order .

Gebruik GROUP_CONCAT() om een ​​reeks "broodkruimels" te maken van de order van elk in de keten van voorouders, en dit wordt een tekenreeks waarop u kunt sorteren om de gewenste menuvolgorde te krijgen.

SELECT m.*, GROUP_CONCAT(o.`order` ORDER BY a.length DESC) AS breadcrumbs
FROM menu AS m
INNER JOIN closure AS a ON a.descendant = m.id
INNER JOIN menu AS o ON a.ancestor = o.id
GROUP BY m.id
ORDER BY breadcrumbs;

+----+----------+-------+-------------+
| id | name     | order | breadcrumbs |
+----+----------+-------+-------------+
|  1 | Father1  |     0 | 0           |
|  3 | Son      |     0 | 0,0         |
|  4 | Child    |     1 | 0,0,1       |
|  5 | Grandson |     2 | 0,0,1,2     |
|  2 | Father2  |     1 | 1           |
+----+----------+-------+-------------+

Merk op dat de broodkruimels als een tekenreeks worden gesorteerd, dus als je een order . hebt, getallen met 2 of 3 cijfers, krijg je onregelmatige resultaten. Zorg ervoor dat uw order nummers hebben allemaal hetzelfde aantal cijfers.

Als alternatief kunt u de broodkruimels gewoon in uw oorspronkelijke menutabel opslaan:

ALTER TABLE menu ADD COLUMN breadcrumbs VARCHAR(255);
UPDATE menu SET breadcrumbs = '0,0,1,2' WHERE id = 5;
etc.

Dan kunt u een eenvoudigere vraag stellen:

SELECT * FROM menu ORDER BY breadcrumbs;

Maar dan is het aan jou om handmatig alle betrokken breadcrumb-strings opnieuw te berekenen, als je ooit de volgorde van de menu-items verandert.



  1. Bestanden opslaan in database versus bestandssysteem

  2. Moet een afzonderlijke combinatie van twee velden opvragen, samen met een telling van die verschillende combinaties

  3. Een optimale omgeving instellen voor PostgreSQL

  4. Agent Decomission in EM13c