php-resource



Zurück   PHP-Scripte PHP-Tutorials PHP-Jobs und vieles mehr > Entwicklung > SQL / Datenbanken
 

Login

 
eingeloggt bleiben
star Jetzt registrieren   star Passwort vergessen
 

 

 


SQL / Datenbanken Probleme mit SQL? Hier könnt ihr eure Fragen zu SQL (MySQL, PostgreSQL, MS-SQL und andere ANSI-SQL Server) los werden.

Antwort
 
LinkBack Themen-Optionen Thema bewerten
  #1 (permalink)  
Alt 24-02-2010, 23:20
carapau
 Registrierter Benutzer
Links : Onlinestatus : carapau ist offline
Registriert seit: Aug 2005
Ort: Bielefeld
Beiträge: 347
carapau ist zur Zeit noch ein unbeschriebenes Blatt
Standard MySQL Bäume (nested sets) - Fragen bzgl. Update

Nabend zusammen!

Ich beschäftige mich momentan mit MySQL Bäumen und benutze folgende Vorlage: Nested Sets – Verschachtelte Bäume mit MySQL - Arne Klempert

Mein Baum sieht so aus:
Code:
- Politik
-- Inland
--- Berlin
--- München
--- Kiel
-- Ausland
--- USA
Das Auslesen inkl. Anzahl der "Kinder" und des Levels funktioniert, das Einfügen neuer Werte auch.

Allerdings weiß ich nicht, wie ich am besten(!) folgendes erreiche:
1. Position innerhalb eines Levels tauschen: "Inland" mit "Ausland".
2. Levelübergreifend tauschen: "Ausland" in den Zweig "Inland" verschieben.

Würde mich freuen, wenn ihr mir die SQL Statements posten könntet - am besten mit kurzer Erklärung. Die ganzen Informationen sind noch nicht ganz gesackt.

Gruß
carapau
__________________
Lasst euch nicht lumpen, hoch den Humpen!
Mit Zitat antworten
  #2 (permalink)  
Alt 25-02-2010, 00:59
AmicaNoctis
  Moderatorin
Links : Onlinestatus : AmicaNoctis ist offline
Registriert seit: Jul 2009
Beiträge: 5.709
Blog-Einträge: 9
AmicaNoctis sorgt für eine eindrucksvolle AtmosphäreAmicaNoctis sorgt für eine eindrucksvolle Atmosphäre
Standard

Hallo,

eigentlich ist das nicht so schwierig. Die einfachste Variante besteht ja darin, den Teilbaum zu entfernen und woanders wieder einzufügen.

Um zwei Kinder eines Knotens (also selbe Ebene) aber effizienter zu tauschen, wird es etwas knifflig. Erstens vom Statement her und zweitens deshalb, weil du dann keinen UNIQUE INDEX auf lft und rgt haben darfst. Während des UPDATE entstehen nämlich kurzzeitig Duplikate. Hier musst du also sehr sorgfältig Sicherheit gegen Performance abwägen.

Code:
update tree
set
	left = left + @offset := if (left < least(:al, :bl) or left > greatest(:ar, :br),
		0,
		if (left > least(:ar, :br) and right < greatest(:al, :bl),
			greatest(:ar, :br) - greatest(:al, :bl) - least(:ar, :br) + least(:al, :bl),
			if (left < greatest(:al, :bl),
				greatest(:ar, :br) - least(:ar, :br),
				least(:al, :bl) - greatest(:al, :bl)
			)
		)
	),
	right = right + @offset;
Für :al musst du dann den lft-Wert des einen Teilbaums (A) und für :ar dessen rgt-Wert übergeben. Für den zweiten Teilbaum (B) übergibst du den lft-Wert als :bl und den rgt-Wert als :br.

Edit: Wenn du die beiden Teilbäume schon vorsortiert übergibst, kannst du sogar noch auf die ganzen greatest- und least-Aufrufe verzichten:

Code:
update tree
set
	left = left + @offset := if (left < :al or left > :br,
		0,
		if (left > :ar and right < :bl,
			:br - :bl - :ar + :al,
			if (left < :bl, :br - :ar, :al - :bl)
		)
	),
	right = right + @offset;
Der Teilbaum A muss dann der mit den niedrigeren Werten sein und B der mit den höheren.

Das Statement unterstützt auch nicht benachbarte Teilbäume, aber sie müssen Geschwister sein, also direkt in demselben Elternknoten liegen.

Für deinen 2. Anwendungsfall kommst du trotzdem besser, wenn du den Teilbaum aushängst und neu einhängst.

Gruß,

Amica
__________________
Hast du die Grundlagen zur Fehlersuche gelesen? Hast du Code-Tags benutzt?
Hast du als URL oder Domain-Beispiele example.com, example.net oder example.org benutzt?
Super, danke!

Geändert von AmicaNoctis (25-02-2010 um 13:46 Uhr)
Mit Zitat antworten
  #3 (permalink)  
Alt 25-02-2010, 13:10
AmicaNoctis
  Moderatorin
Links : Onlinestatus : AmicaNoctis ist offline
Registriert seit: Jul 2009
Beiträge: 5.709
Blog-Einträge: 9
AmicaNoctis sorgt für eine eindrucksvolle AtmosphäreAmicaNoctis sorgt für eine eindrucksvolle Atmosphäre
Standard

Hallo nochmal,

ich hab jetzt auch eine Single-Statement-Lösung für die zweite Aufgabe, also das Verschieben eines beliebigen Teilbaums an eine beliebige neue Stelle:

[Nested Set] move subtree

Das deckt also auch den ersten Fall gleich mit ab.

Gruß,

Amica
__________________
Hast du die Grundlagen zur Fehlersuche gelesen? Hast du Code-Tags benutzt?
Hast du als URL oder Domain-Beispiele example.com, example.net oder example.org benutzt?
Super, danke!

Geändert von AmicaNoctis (25-02-2010 um 15:06 Uhr)
Mit Zitat antworten
  #4 (permalink)  
Alt 26-02-2010, 21:08
carapau
 Registrierter Benutzer
Links : Onlinestatus : carapau ist offline
Registriert seit: Aug 2005
Ort: Bielefeld
Beiträge: 347
carapau ist zur Zeit noch ein unbeschriebenes Blatt
Standard

Zitat:
Zitat von AmicaNoctis Beitrag anzeigen
...
ich hab jetzt auch eine Single-Statement-Lösung für die zweite Aufgabe, also das Verschieben eines beliebigen Teilbaums an eine beliebige neue Stelle:

[Nested Set] move subtree ...
Saubere Arbeit, klappt perfekt - Danke!!!

Jetzt hätte ich noch ein kleines Problem: das Löschen. Hat da jemand was professionelles im Ärmel?

Gruß
carapau
__________________
Lasst euch nicht lumpen, hoch den Humpen!
Mit Zitat antworten
  #5 (permalink)  
Alt 26-02-2010, 21:42
AmicaNoctis
  Moderatorin
Links : Onlinestatus : AmicaNoctis ist offline
Registriert seit: Jul 2009
Beiträge: 5.709
Blog-Einträge: 9
AmicaNoctis sorgt für eine eindrucksvolle AtmosphäreAmicaNoctis sorgt für eine eindrucksvolle Atmosphäre
Standard

Mit so viel Inspiration solltest du das bisschen Löschen selbst hinbekommen.

Wenn nicht, findest du das in praktisch jedem Nested-Sets-Tutorial. Wie man Google benutzt, weißt du hoffentlich?

Gruß,

Amica
__________________
Hast du die Grundlagen zur Fehlersuche gelesen? Hast du Code-Tags benutzt?
Hast du als URL oder Domain-Beispiele example.com, example.net oder example.org benutzt?
Super, danke!
Mit Zitat antworten
  #6 (permalink)  
Alt 27-02-2010, 00:23
carapau
 Registrierter Benutzer
Links : Onlinestatus : carapau ist offline
Registriert seit: Aug 2005
Ort: Bielefeld
Beiträge: 347
carapau ist zur Zeit noch ein unbeschriebenes Blatt
Standard

Zitat:
Zitat von AmicaNoctis Beitrag anzeigen
Mit so viel Inspiration solltest du das bisschen Löschen selbst hinbekommen.

Wenn nicht, findest du das in praktisch jedem Nested-Sets-Tutorial. Wie man Google benutzt, weißt du hoffentlich?

Gruß,

Amica
Ich habs jetzt einfach mit mehreren Queries gemacht, funktioniert wunderbar.
__________________
Lasst euch nicht lumpen, hoch den Humpen!
Mit Zitat antworten
  #7 (permalink)  
Alt 27-02-2010, 00:37
AmicaNoctis
  Moderatorin
Links : Onlinestatus : AmicaNoctis ist offline
Registriert seit: Jul 2009
Beiträge: 5.709
Blog-Einträge: 9
AmicaNoctis sorgt für eine eindrucksvolle AtmosphäreAmicaNoctis sorgt für eine eindrucksvolle Atmosphäre
Standard

Ja, geht auch nur mit mehreren. Ein DELETE Statement und ein UPDATE Statement um die lft/rgt-Werte zu verringern.
__________________
Hast du die Grundlagen zur Fehlersuche gelesen? Hast du Code-Tags benutzt?
Hast du als URL oder Domain-Beispiele example.com, example.net oder example.org benutzt?
Super, danke!
Mit Zitat antworten
  #8 (permalink)  
Alt 15-07-2010, 12:39
sqeez3r
 Registrierter Benutzer
Links : Onlinestatus : sqeez3r ist offline
Registriert seit: Jul 2010
Beiträge: 3
sqeez3r befindet sich auf einem aufstrebenden Ast
Standard

Hallo!

Während ich die einfacheren Operationen wie Einfügen und Löschen noch problemlos alleine "entwickeln", habe ich bei der Suche nach einer Lösung zum Verschieben google bemüht und bin hier gelandet.

Amica, deine 1-Query-Lösung ist sehr beeindruckend! Allerdings verstehe ich nicht ganz, wie sie einzusetzen ist: Wenn ich die Parameter l, r und p schon in PHP mit den Werten des zu verschiebenden Subbaumes bzw. des Ziel-Subbaumes fülle, kommt am Ende so etwas wie "where 4 < 5 or 5 < 1" heraus, was für mich keinen Sinn gibt.

Vielleicht kann mir jemand auf die Sprünge helfen? DANKE!
Mit Zitat antworten
  #9 (permalink)  
Alt 15-07-2010, 12:59
AmicaNoctis
  Moderatorin
Links : Onlinestatus : AmicaNoctis ist offline
Registriert seit: Jul 2009
Beiträge: 5.709
Blog-Einträge: 9
AmicaNoctis sorgt für eine eindrucksvolle AtmosphäreAmicaNoctis sorgt für eine eindrucksvolle Atmosphäre
Standard

Zitat:
Zitat von sqeez3r Beitrag anzeigen
kommt am Ende so etwas wie "where 4 < 5 or 5 < 1" heraus, was für mich keinen Sinn gibt.
Warum nicht? Vier ist doch kleiner als fünf: Bedingung erfüllt.

Nur wenn z. B. l = 12; r = 19; p = 15 ist, ergibt sich 19 < 15 or 15 < 12 womit die Bedingung nicht erfüllt ist, weil man dann einen Teilbaum in sich selbst verschieben würde, was nicht gehen kann und darf.
__________________
Hast du die Grundlagen zur Fehlersuche gelesen? Hast du Code-Tags benutzt?
Hast du als URL oder Domain-Beispiele example.com, example.net oder example.org benutzt?
Super, danke!
Mit Zitat antworten
  #10 (permalink)  
Alt 15-07-2010, 13:51
sqeez3r
 Registrierter Benutzer
Links : Onlinestatus : sqeez3r ist offline
Registriert seit: Jul 2010
Beiträge: 3
sqeez3r befindet sich auf einem aufstrebenden Ast
Standard

Achso, ok ich verstehe.

Trotzdem funktioniert der Query bei mir nicht. Wahrscheinlich mache ich etwas falsch!

Ich habe nur zwei Teilbäume:
zsb1 5 8
zsb2 1 4
blech von zsb1 6 7
blech von zsb2 2 3

Wenn ich nun den Eintrag "zsb2" (inkl. "blech von zsb2") in "zsb1" verschieben möchte, sieht das so aus:

Code:
$result = $this->query("SELECT `liGrenze`, `reGrenze` FROM `bauteil` WHERE `Teilenr` = '" . $id . "'");
        $bauteil = $result->fetch_object();
        $result = $this->query("SELECT `liGrenze`, `reGrenze` FROM `bauteil` WHERE `Teilenr` = '" . $zielID . "'");
        $zielBauteil = $result->fetch_object();

$this->query("
        update bauteil
        set
    liGrenze = liGrenze + if (".$zielBauteil->liGrenze." > ".$bauteil->reGrenze.",
        if (".$bauteil->reGrenze." < liGrenze and liGrenze < ".$zielBauteil->liGrenze.",
            ".$bauteil->liGrenze." - ".$bauteil->reGrenze." - 1,
            if (".$bauteil->liGrenze." <= liGrenze and liGrenze < ".$bauteil->reGrenze.",
                ".$zielBauteil->liGrenze." - ".$bauteil->reGrenze." - 1,
                0
            )
        ),
        if (".$zielBauteil->liGrenze." <= liGrenze and liGrenze < ".$bauteil->liGrenze.",
            ".$bauteil->reGrenze." - ".$bauteil->liGrenze." + 1,
            if (".$bauteil->liGrenze." <= liGrenze and liGrenze < ".$bauteil->reGrenze.",
                ".$zielBauteil->liGrenze." - ".$bauteil->liGrenze.",
                0
            )
        )
    ),
    reGrenze = reGrenze + if (".$zielBauteil->liGrenze." > ".$bauteil->reGrenze.",
        if (".$bauteil->reGrenze." < reGrenze and reGrenze < ".$zielBauteil->liGrenze.",
            ".$bauteil->liGrenze." - ".$bauteil->reGrenze." - 1,
            if (".$bauteil->liGrenze." < reGrenze and reGrenze <= ".$bauteil->reGrenze.",
                ".$zielBauteil->liGrenze." - ".$bauteil->reGrenze." - 1,
                0
            )
        ),
        if (".$zielBauteil->liGrenze." <= reGrenze and reGrenze < ".$bauteil->liGrenze.",
            ".$bauteil->reGrenze." - ".$bauteil->liGrenze." + 1,
            if (".$bauteil->liGrenze." < reGrenze and reGrenze <= ".$bauteil->reGrenze.",
                ".$zielBauteil->liGrenze." - ".$bauteil->liGrenze.",
                0
            )
        )
    )
        where ".$bauteil->reGrenze." < ".$zielBauteil->liGrenze." or ".$zielBauteil->liGrenze." < ".$bauteil->liGrenze);
Und am Ende kommt dann das raus:

[Code entfernt, da überlang (>900 Zeichen) und nicht wirklich relevant, Amica]

Es sind allerdings keine Zeilen von dem Qry betroffen.
Sorry, wenn ich mich blöd anstelle

Geändert von AmicaNoctis (15-07-2010 um 14:09 Uhr)
Mit Zitat antworten
  #11 (permalink)  
Alt 15-07-2010, 13:57
AmicaNoctis
  Moderatorin
Links : Onlinestatus : AmicaNoctis ist offline
Registriert seit: Jul 2009
Beiträge: 5.709
Blog-Einträge: 9
AmicaNoctis sorgt für eine eindrucksvolle AtmosphäreAmicaNoctis sorgt für eine eindrucksvolle Atmosphäre
Standard

Dann muss dein p 8 sein, nicht 5.

Zitat:
-- moves a subtree before the specified position
-- if the position is the rgt of a node, the subtree will be its last child
-- if the position is the lft of a node, the subtree will be inserted before
-- @param l the lft of the subtree to move
-- @param r the rgt of the subtree to move
-- @param p the position to move the subtree before
Übrigens: Das Statement kannst du ganz leicht mit den Parametern füllen, indem du prepared Statements verwendest. Dann brauchst du das nicht so umständlich zusammenstückeln.
__________________
Hast du die Grundlagen zur Fehlersuche gelesen? Hast du Code-Tags benutzt?
Hast du als URL oder Domain-Beispiele example.com, example.net oder example.org benutzt?
Super, danke!

Geändert von AmicaNoctis (15-07-2010 um 14:10 Uhr)
Mit Zitat antworten
  #12 (permalink)  
Alt 15-07-2010, 17:34
sqeez3r
 Registrierter Benutzer
Links : Onlinestatus : sqeez3r ist offline
Registriert seit: Jul 2010
Beiträge: 3
sqeez3r befindet sich auf einem aufstrebenden Ast
Standard

Hallo Amica!

Danke nochmals für deine Hilfe. So funktioniert es einwandfrei.
Das ganze in einem Statement ist echt super, denn so erspart man sich auch den ganzen "LOCK TABLES" Kram

Das Ganze als Prepared Statement umzusetzen ist auch eine gute Idee, das mache ich direkt mal.
Mit Zitat antworten
Antwort

Lesezeichen


Aktive Benutzer in diesem Thema: 1 (Registrierte Benutzer: 0, Gäste: 1)
 

Ähnliche Themen
Thema Autor Forum Antworten Letzter Beitrag
Nested Sets strauberry Off-Topic Diskussionen 8 01-10-2006 18:35
Nested Sets timepoint5 SQL / Datenbanken 1 04-08-2006 08:16
nested sets - mysql tutorial tashideleg SQL / Datenbanken 2 23-04-2005 00:07
Fragen zu Nested Sets acarweb PHP Developer Forum 1 12-10-2004 17:12
Das 'Nested Sets' Modell - Bäume mit SQL Berni Tutorials 0 06-01-2003 00:33

Themen-Optionen
Thema bewerten
Thema bewerten:

Forumregeln
Es ist Ihnen nicht erlaubt, neue Themen zu verfassen.
Es ist Ihnen nicht erlaubt, auf Beiträge zu antworten.
Es ist Ihnen nicht erlaubt, Anhänge hochzuladen.
Es ist Ihnen nicht erlaubt, Ihre Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are an


PHP News

ebiz-trader 7.5.0 mit PHP7 Unterstützung veröffentlicht
ebiz-trader 7.5.0 mit PHP7 Unterstützung veröffentlichtDie bekannte Marktplatzsoftware ebiz-trader ist in der Version 7.5.0 veröffentlicht worden.

28.05.2018 | Berni

Wissensbestand in Unternehmen
Wissensbestand in UnternehmenLebenslanges Lernen und Weiterbilden sichert Wissensbestand in Unternehmen

25.05.2018 | Berni


 

Aktuelle PHP Scripte

PHP Server Monitor

PHP Server Monitor ist ein Skript, das prüft, ob Ihre Websites und Server betriebsbereit sind.

11.09.2018 Berni | Kategorie: PHP/ Security
PHP WEB STATISTIK ansehen PHP WEB STATISTIK

Die PHP Web Statistik bietet Ihnen ein einfach zu konfigurierendes Script zur Aufzeichnung und grafischen und textuellen Auswertung der Besuchern Ihrer Webseite. Folgende zeitlichen Module sind verfügbar: Jahr, Monat, Tag, Wochentag, Stunde Folgende son

28.08.2018 phpwebstat | Kategorie: PHP/ Counter
Affilinator - Affilinet XML Produktlisten Skript

Die Affilinator Affilinet XML Edition ist ein vollautomatisches Skript zum einlesen und darstellen der Affili.net (Partnerprogramm Netzwerk) Produktlisten und Produktdaten. Im Grunde gibt der Webmaster seine Affilinet PartnerID ein und hat dann unmittelb

27.08.2018 freefrank@ | Kategorie: PHP/ Partnerprogramme
 Alle PHP Scripte anzeigen

Alle Zeitangaben in WEZ +2. Es ist jetzt 15:56 Uhr.