MySQL Nested Sets - Wie Eltern des Knotens zu finden?
-
05-07-2019 - |
Frage
Ich habe Ihren Lauf von der Mühle verschachtelt Sethierarchie Typ-Setup mit den folgenden Spalten:
Tabellenname:
myset
Spalten:
id, name, lft, rgt
Kennt jemand eine Abfrage der Eltern einen Knotens bestimmen?
las ich ein paar Orte, die es praktisch ist auch ein haben, parent_id Spalte in der Tabelle Übersicht über diese zu halten, aber es scheint überflüssig, und es scheint, wie es nicht synchron mit dem verschachtelten bekommen könnte gesetzt, wenn eine Abfrage falsch ausgeführt wurde, wenn das Hinzufügen / Entfernen / innerhalb des Satzes bewegt etwas.
Lösung
Lesen Sie diese Frage . Es ist ähnlich wie bei Ihnen. Ich habe dort eine Abfrage geschrieben Sie benötigen.
SELECT title, (SELECT TOP 1 title
FROM tree t2
WHERE t2.lft < t1.lft AND t2.rgt > t1.rgt
ORDER BY t2.rgt-t1.rgt ASC) AS parent
FROM tree t1
ORDER BY rgt-lft DESC
Ich hoffe, es ist das, was Sie brauchen.
Für die folgende Tabelle:
+-------------+----------------------+-----+-----+
| category_id | name | lft | rgt |
+-------------+----------------------+-----+-----+
| 1 | ELECTRONICS | 1 | 20 |
| 2 | TELEVISIONS | 2 | 9 |
| 3 | TUBE | 3 | 4 |
| 4 | LCD | 5 | 6 |
| 5 | PLASMA | 7 | 8 |
| 6 | PORTABLE ELECTRONICS | 10 | 19 |
| 7 | MP3 PLAYERS | 11 | 14 |
| 8 | FLASH | 12 | 13 |
| 9 | CD PLAYERS | 15 | 16 |
| 10 | 2 WAY RADIOS | 17 | 18 |
es erzeugt die Ausgabe:
title | parent
----------------------------------------------
ELECTRONICS | NULL
PORTABLE ELECTRONICS | ELECTRONICS
TELEVISIONS | ELECTRONICS
MP3 PLAYERS | PORTABLE ELECTRONICS
FLASH | MP3 PLAYERS
CD PLAYERS | PORTABLE ELECTRONICS
2 WAY RADIOS | PORTABLE ELECTRONICS
TUBE | TELEVISIONS
LCD | TELEVISIONS
PLASMA | TELEVISIONS
Andere Tipps
TOP ist ein MSSQL Befehl, Verwendung LIMIT für MySQL:
SELECT title, (SELECT title
FROM tree t2
WHERE t2.lft < t1.lft AND t2.rgt > t1.rgt
ORDER BY t2.rgt-t1.rgt ASC
LIMIT 1)
AS parent FROM tree t1
ORDER BY (rgt-lft) DESC
Sollte es tun ..
nur auf diese Antworten hinzuzufügen, die mir sehr geholfen,
ich brauchte die unmittelbar übergeordneten einen Knotens zu finden, sowie die obersten Ebene Eltern einen Knotenkette in einigen Fällen
i verwendet, um die folgenden als Basis die Elemente in Kind-to-Eltern zu erhalten, um
SELECT parent.* FROM
nested_set node,
nested_set parent
WHERE (
node.set_left BETWEEN parent.set_left AND parent.set_right
)
AND node.set_id={CHILD_NODE_ID_HERE}
ORDER BY parent.set_right - parent.set_left
#LIMIT 1,1
es ist dann eine Sache der LIMIT 1,1
der Zugabe der zweiten Reihe nur zu erfassen, die die unmittelbar übergeordnete würde
Es sollte auch beachtet werden, dass mit der obigen Abfrage, wenn der Knoten selbst die obersten Ebene Eltern ist, dann wäre es nicht ein unmittelbaren Elternteil , so mit dem LIMIT 1,1
sollte es ein leeres Ergebnis zurück set
der obersten Ebene Eltern bekommen ich den Auftrag durch Klausel umgekehrt, enthalten einen Scheck, wenn der Knoten selbst die oberste Mutter ist, und begrenzt das Ergebnis auf die erste Zeile
SELECT parent.* AS top_level_right FROM
nested_set node,
nested_set parent
WHERE (
node.set_left >= parent.set_left
AND node.set_left <= parent.set_right
)
AND node.set_id={CHILD_NODE_ID_HERE}
ORDER BY parent.set_left - parent.set_right
LIMIT 1
in der letzten Abfrage verwendet i >= <=
Betreiber, so dass der ausgewählte Bereich die Knoten Kind umfasst, wenn es passiert auch der Top-Level-Elternteil sein
Ich hatte ein Problem mit Lucasz Abfrage. Meine Version von MySQL nicht verstehen, den TOP-Befehl. Ich hatte stattdessen LIMIT zu verwenden. Hier ist der überarbeitete Code.
SELECT
`id`,
(SELECT
`id`
FROM
`[*** YOUR TABLE ***]` AS `t2`
WHERE
`t2`.`left_id` < `t1`.`left_id`AND
`t2`.`right_id` > `t1`.`right_id`
ORDER BY
`t2`.`right_id`-`t1`.`right_id`ASC
LIMIT
1) AS `parent`
FROM
`[*** YOUR TABLE ***]` AS `t1`
WHERE
`t1`.`id` = [*** ID OF THE NODE WHOS PARENT YOU WISH TO LOOKUP ***]
ORDER BY
`right_id`-`left_id` DESC
Offensichtlich ändern das Zeug in die [] 's an Ihre Bedürfnisse anzupassen. Entfernen Sie auch die [] 's. Diese Abfrage gibt nur eine Zeile. Wie so ...
id parent
7 3
select * from myset
where lft < :lftOfCurrent and rgt > :lftOfCurrent
order lft desc
limit 1
Sie können einen max verwenden, anstatt um / Limit und Sie vielleicht ein anderes Schlüsselwort müssen die Ergebnisse eine Zeile abhängig von Ihrer Datenbank zu begrenzen. Zwischen statt
SELECT parent.name
FROM myset AS node, myset AS parent
WHERE parent.lft < node.lft
AND parent.rgt > node.rgt
AND node.id = {YOUR CATEGORY ID}
ORDER BY ( parent.rgt - parent.lft ) ASC LIMIT 1;
Alle Vorfahren zurück von
SELECT id FROM thetable
WHERE x BETWEEN lft and rgt;
So ist der direkte Elternteil ist der Vorfahr mit der kleinsten Differenz zwischen LFT und RGT.
SELECT id FROM thetable
WHERE x BETWEEN lft and rgt
ORDER BY (rgt-lft)
LIMIT 1
Der Code von spankmaster79 war nicht ganz falsch. Ich änderte seinen Code und es hat funktioniert.
SELECT parent . * FROM Nested_Category AS node, Nested_Category AS parent
enter code hereWHERE node.leftSide
BETWEEN parent.leftSide
AND parent.rightSide
AND node.id ='Enter the Node ID'
ORDER BY (
parent.rightSide - parent.leftSide
)
LIMIT 1 , 1