sql >> Databáze >  >> RDS >> Mysql

MySQL strom seřazený podle rodiče a potomka

Kromě metod uvedených na blogu Mika Hillyera existují i ​​jiné způsoby, jak organizovat hierarchická data. Rád používám metodu, kterou nazývám tranzitivní uzavírací tabulka nebo zkráceně uzavírací stůl. V tomto designu ukládáte každou cestu hierarchií jako páry předek/potomek.

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);

Všimněte si, že tato sada obsahuje dokonce i "cesty" délky nula, tj. položka nabídky je "rodič" sama o sobě.

Nyní se můžete připojit ke každé položce nabídky m ke každé jeho sadě předků a , připojením k cestám, kde m je descantant. Odtud se připojte zpět k položce nabídky o který je v množině předků a máte přístup k order .

Pomocí GROUP_CONCAT() vytvořte řetězec "drobečky" z order každého v řetězci předků, a to se stane řetězcem, podle kterého můžete seřadit, abyste získali požadované pořadí nabídky.

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

Všimněte si, že strouhanka se třídí jako řetězec, takže pokud máte nějakou order čísla se 2 nebo 3 číslicemi, získáte nepravidelné výsledky. Zkontrolujte svou order všechna čísla mají stejný počet číslic.

Alternativně můžete jednoduše uložit strouhankové řetězce do vaší původní tabulky nabídky:

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

Pak můžete udělat jednodušší dotaz:

SELECT * FROM menu ORDER BY breadcrumbs;

Pak je ale na vás, abyste ručně přepočítali všechny dotčené řetězce drobečkové navigace, pokud někdy změníte pořadí položek nabídky.



  1. Socket File /var/pgsql_socket/.s.PGSQL.5432 chybí v Mountain Lion (OS X Server)

  2. Jak vypsat všechny tabulky v Oracle

  3. Úvod do databází časových řad

  4. Funkce SQL Row_Number() v klauzuli Where