Ordner/Bilder Tree suche mit SQL

slimox

Mitglied
Hallo zusamen,

Ich habe einen Ordnerbaum in der Tabelle "Ordnerbaum". Diese ist sehr einfach aufgebaut:
Der Ordner "Bilder" hat z.B. die id 4. In der gleichen Tabelle sind auch seine Kinder. Diese haben in der Spalte "parentId" alle die 4 vom Ordener "Bilder". Das heisst es kann beliebig viele Unterordner geben.
In den Ordnern kann es auf allen Stufen Bilder haben. Es gibt eine Spalte die "was" heisst. Ein enum() in welchem "bild" oder "ordner" steht.

Das habe ich und das funktioniert auch bestets.

Was ich nicht schaffe:
Es gibt ein Suche nach Bilder- Ordnernamen. Meine aktuelle Suche:
Code:
                        SELECT id, name, was, 
                        IF( name  REGEXP '$search', 3, 0 ) AS NA,
                        FROM Ordnerbaum
                        WHERE
                        name REGEXP '$search'
                        ORDER BY NA DESC
                        LIMIT $page, 30;
So kriege ich alle Bilder und Ordner.
Wenn ich das ganze mit php auslese, kann es ja gut sein, dass ein Ergebniss ein Ordner ist. Für diesen Fall habe ich mir eine Methode gemacht, die sich selbst immer wieder aufruf bis es keinen Unterordner mehr gibt
PHP:
private function getBilderInOrdner($ordnerId){
            $sql = "SELECT id, name, was 
                    FROM Ordnerbaum
                    WHERE  parentId = '$ordnerId'";
            $qry = $this->db->query($sql);
            foreach ($qry->result() as $row){
                    if($row->was == 'bild'){
                        $this->Bilder[] = array(/*Bild Infos*/);
                    }else{
                        //Wenn es ein Ordner ist -> gehe in diesen
                        $this->getBilderInOrdner($row->id);
                    }
            }
        }
Mit dieser Methode können alle Bilder eines Ordners inkl. aller Unterordners ausgegeben werden.
Da ich das ganze mit paging machen möchte, geht das mit dieser Methode nicht.
Hat jemand eine Idee, wie man das ganze in eine SQL abrage steckt?
Hätte ich das, möchte ich versuchen, dass man ab einem beliebigen Unterordner suchen kann und es nur Bilder in diesem oder von Unterunterordner gefunden werden. ;)
Ich haffe, dass nicht nur ich diese Frage verstehe ;) ;):p:D
 
CODE von yaslaw:
Code:
SELECT
    id
FROM
    (
        SELECT  
            @id AS id,
            @id := IF(@id IS NOT NULL, (SELECT parentID FROM nav WHERE id = @id), NULL) AS parentID
        FROM
            nav,
            (SELECT @id := 9) AS vars
        WHERE
            @id IS NOT NULL
    ) AS dat

Gibt alle Ordner bis zum obersten an. Was ich versuche, von id = 9 alle Bilder die in allen Unterodner sind ausgeben :D Ist das möglich, da es in einem Ordner mehrere Unterordner haben kann?
 
Zuletzt bearbeitet:
Ich gehe da von dem zweiten SQL auf meiner Seite aus.
Wenn man den GROUP BY weglässt, hat man eine Aufstellung mit jeder ID und dazu jede parentid.
Da noch ein WHERE auf die parentid mit der gesuchten Ordner-ID und schon hat man eine auflistung aller ids die darunter liegen (inklusive der Start-ID)
SQL:
SELECT
    id
FROM
    (
        SELECT
            -- Zeilennummer. Wird später für die Sortierung des GROUP_CONCAT verwednet
            @rownum := @rownum+1 AS rownum,
            -- id die für den Pfad verwendet wird
            IF(@lastid <> mylist.id, @id := mylist.id, @id) AS pathid,
            -- Die Start-Id.
            @lastid := mylist.id AS id,
            -- bestimmen der nächsten id im Path
            @id := (SELECT parentID FROM nav  WHERE id = @id) AS parentID
        FROM
            -- Variablen initialisieren
            (SELECT @id := 0, @lastid := 0, @rownum := 0) AS vars,
            -- Die Tabelle mit sich selber multiplizieren umd genügend
            -- Zeilen zur Verfügung zu haben
            (SELECT id FROM nav) AS myloop,
            (SELECT id FROM nav) AS mylist
    ) AS t
WHERE
-- ID des Startordners
    pathid = 2

Mit der id 2 meines Beipiels auf dem Wiki ergibt dass dan die folgenden Resultate
Code:
id
----
2
3
8
9
10

PS: Danke für den neuen Fall. Ich kann mit dem Script gleich mein Wiki erweitern....
 
Zuletzt bearbeitet von einem Moderator:
Super Sache, ich habe in der Zwischenzeit die verschiedenen Tree's angeschaut. Das Tree das du im Wiki hast ist ein "Adjacency" Tree. Es ist einiges einfacher hier neue Kinder hinzuzufügen oder Kinder zu bewegen. Der grosse Nachteil, die ausgabe ist echt kniflig ;)

Beim "Nested" Tree sind manipulationen komplexer, dafür ist die ausgabe viel einfacher.

Hier ein Link wo die zwei verglichen werden:http://dev.mysql.com/tech-resources/articles/hierarchical-data.html

So sieht der SQL aus wenn ich ab einem bestimmten Kind alle darin enthaltenen haben möchte (Nested Tree):
Code:
                    SELECT node.name
                    FROM Ordnerbaum AS node,
                    Ordnerbaum AS parent
                    WHERE node.lft BETWEEN parent.lft AND parent.rgt
                    AND parent.name = 'TUTORIALS BILDER'
                    ORDER BY node.lft;

Du (yaslaw) bist genial, was du mit SQL alles machen kannst! Besten Dank trozdem! :p
 
Zuletzt bearbeitet:
Da ist doch noch was bei mir nicht ganz klar, ich suche in allen Feldern ob der Suchstring vorkommt. Wenn der String einen Ordner findet, soll es alle KindesKinder (nur Bilder) von diesem Ordner ausgeben:
Code:
            SELECT id, name, was, 
            IF( name  REGEXP '$search', 3, 0 ) AS NA,
            IF( was = 'ordner', ALLE KINDER, DIESES BILD)
            FROM Ordnerbaum
            WHERE
            name REGEXP '$search'
            ORDER BY NA DESC
            LIMIT $page, 30;
Habe keine Idee, wie ich im Fall dass es ein Ordner ist diese SQL ausführen kann, natürlich im laufenden SQL ;)

Code:
SELECT node.name
                    FROM Ordnerbaum AS node,
                    Ordnerbaum AS parent
                    WHERE node.lft BETWEEN parent.lft AND parent.rgt
                    AND parent.name = 'TUTORIALS BILDER'
                    ORDER BY node.lft;
Hast du eine Idee? Wenn möglich mit dem Nested ;) :p
 
Die Lösung auf der Seite ist hübsch. Aber mit einem JOIN wird übersichtlicher, was nur dazu ist um den parent zu selektionieren und was dazu da ist um die Tabellen zu verbinden
Dann hast du im WHERE-Teil nur noch die Suche nach den Oberordnern.

SQL:
SELECT 
	id, 
FROM 
	Ordnerbaum AS node
	INNER JOIN Ordnerbaum AS parent
		ON node.lft BETWEEN parent.lft AND parent.rgt
WHERE
	parent.name REGEXP '{$search}'
 
Zuletzt bearbeitet von einem Moderator:
Hehe, also ich schreibe die Frage etwas anders, ich möchte mit einer Suche in der Tabelle Ordnerbaum im Feld "name" suchen. Wenn im Feld "was" ordner steht, soll es alle Bilder von allen KindesKindern holen, egal was sie für einen Namen haben.

Code:
            ID -   was   - name        - lft - rgt
            1  -  ordner - Deutsch     -  1  - 20
            2  -  ordner - Deutschland -  2  - 7
            3  -  bild   - Bild1       -  3  - 4
            4  -  bild   - Bild2       -  5  - 6
            5  -  bild   - Deutsches   -  8  - 9
            6  -  ordner - Elefant     -  10 - 19
            7  -  bild   - Klein       -  11 - 12
            8  -  ordner - Andere      -  13 - 18
            9  -  bild   - Grösser     -  14 - 15
            10 -  bild   - Am Grössten -  16 - 17
$search ist "Deutsch" sollte als ergebniss die ID 3, 4, 5, 7, 9, 10 sein
$search ist "Bild" sollte als ergebniss die ID 3, 4 sein
$search ist "Deutschland" sollte als ergebniss die ID 3, 4 sein
$search ist "Elefant" sollte als ergebniss die ID 7, 9, 10 sein

Ist das so möglich? :rolleyes:
 
Zuletzt bearbeitet:

Neue Beiträge

Zurück