So wählen Sie unmittelbare Kinder und Vorfahren alle in derselben Abfrage

Ich arbeite mit einer treestruktur in MySQL, die unter Verwendung des geschachtelten Mengenmodells dargestellt wird.

Ich hoffe, einige von Ihnen sql Experten können mir helfen, eine SELECT-Abfrage zu erstellen.

Ich möchte in der Lage sein, eine Reihe von Knoten mit LIKE übereinstimmen. Für jeden übereinstimmenden Knoten benötige ich auch eine durch Komma aufgetriggerse list der Vorfahren dieses Knotens und eine Komma-aufgetriggerse list der unmittelbaren Nachfolger dieses Knotens.

Ich bin mir nicht sicher, wo ich damit anfangen soll – wenn so etwas in einer einzigen Abfrage überhaupt möglich ist. (Momentan bearbeite ich dies mit einer Abfrage innerhalb einer loop.) Was ich mir erhoffe, ist eine Ergebnismenge, die in etwa so aussehen könnte ….

Beginnend mit der characterfolge "qu" und die Tabelle "Body" abfragend bekomme ich …

Node | Parent Nodes | Immediate Children Quads Leg, Lower Body, Muslces Vastus Lateralus, Vastus Medialis, Rectus Femoris Obliques Core, Trunk, Muscles Inner obliques, outer obliques 

Irgendwelche Vorschläge, wie dies ohne loops-Abfragen zu erreichen wäre, würden sehr geschätzt.

Solutions Collecting From Web of "So wählen Sie unmittelbare Kinder und Vorfahren alle in derselben Abfrage"

Während ich nickf zustimme, dass das schlecht und dreckig ist, macht es immer noch Spaß, also hier:

 SELECT base.left_id, base.ancestors, GROUP_CONCAT(children.left_id) children FROM ( SELECT base.left_id , GROUP_CONCAT(ancestors.left_id) ancestors FROM nested_set base LEFT JOIN nested_set ancestors ON base.left_id BETWEEN ancestors.left_id AND ancestors.right_id WHERE base.name LIKE '%criteria%' GROUP BY base.left_id ) base LEFT JOIN nested_set children ON children.left_id BETWEEN base.left_id AND base.right_id LEFT JOIN nested_set inbetween ON inbetween.left_id BETWEEN base.left_id AND base.right_id AND children.left_id BETWEEN inbetween.left_id AND inbetween.right_id WHERE inbetween.left_id IS NULL GROUP BY base.left_id 

Grundsätzlich besteht der Trick darin, es in zwei Schritten zu lösen: zuerst, lösen Sie das Vorfahren-Problem, und quetschen Sie die Vorfahren zu einer list mit, dann verwenden Sie dieses Ergebnis, um es für die Kinder zu lösen.

Der Teil der Vorfahren ist relativ einfach, es ist die Unterabfrage in der from-Klausel in meiner Lösung. Die Kinder sind ein bisschen härter. Es funktioniert, indem alle Abkömmlinge genommen werden und dann gefordert wird, dass keine Knoten zwischen dem Basisknoten und den Abkömmlingen existieren, was im Grunde die Abkömmlinge auf nur die Kinder beschränkt.

Es gibt andere Varianten dieser Strategie, um dies zu lösen – zum Beispiel können Sie die Kinder zuerst tun und die Vorfahren mit einer Unterabfrage in der SELECT list lösen.

In einer Abfrage? Ich würde mich nicht kümmern. Das SQL wäre schrecklich und wahrscheinlich nicht einmal so effizient. Teilen Sie jedes Bit in logisch kleinere Abfragen auf: searchn Sie zuerst alle übereinstimmenden Knoten und dann für jedes einzelne die zusätzlichen Informationen, die Sie benötigen.

Ich bin nicht 100% sicher, was Sie wollen, aber wenn ich das richtig verstehe, können Sie dies mit einem normalisierten databaseschema und Unterabfragen erreichen.

Beispielsweise:

Tabelle "nodes" Tabelle "node_parents"

Die "nodes" -Tabelle würde alle Knoten speichern und "node_parents" würde Beziehungen zwischen verschiedenen Knoten zuordnen.

Wenn Sie also LIKE für einen bestimmten Knoten auswählen, können Sie alle seine Eltern und Kinder von node_parents übernehmen.

Sie können die zusätzlichen Informationen mit Joins oder Unterabfragen erfassen.

Diese Frage ist viel schwieriger als ich es in Ihrem anderen Beitrag erwartet habe, aber ich stimme der ersten Antwort nicht zu.

Ich bin ziemlich zuversichtlich, dass es mit einer einzigen Abfrage möglich ist.

Sie müssen SUBQUERIES verwenden und wählen. Haben Sie sich jemals die wirklich gute Demo auf der mySQL-Website zum Adjacency List Model angeschaut?

Da Sie für den "Knoten" LIKE können Sie Sub-Abfragen für Ihre SQL-Abfrage verwenden, um alle Eltern und Eltern zu erhalten. Eine meiner Fragen, auf die ich so etwas gemacht habe, war absolut massiv! Aber es hat funktioniert.

Werfen Sie einen Blick: http://mikehillyer.com/articles/managing-hierarchical-data-in-mysql/

Dies ist nur ein kleiner Codeausschnitt, der zeigt, wie die unmittelbaren Kinder gefunden werden.

 SELECT node.name, (COUNT(parent.name) - (sub_tree.depth + 1)) AS depth FROM nested_category AS node, nested_category AS parent, nested_category AS sub_parent, ( SELECT node.name, (COUNT(parent.name) - 1) AS depth FROM nested_category AS node, nested_category AS parent WHERE node.lft BETWEEN parent.lft AND parent.rgt AND node.name = 'PORTABLE ELECTRONICS' GROUP BY node.name ORDER BY node.lft )AS sub_tree WHERE node.lft BETWEEN parent.lft AND parent.rgt AND node.lft BETWEEN sub_parent.lft AND sub_parent.rgt AND sub_parent.name = sub_tree.name GROUP BY node.name HAVING depth <= 1 ORDER BY node.lft