Kategorie mit samt allen unterkategorien mit einem SQL-Befehl abfragen

Diese Seite verwendet Cookies. Durch die Nutzung unserer Seite erklären Sie sich damit einverstanden, dass wir Cookies setzen. Weitere Informationen

  • Kategorie mit samt allen unterkategorien mit einem SQL-Befehl abfragen

    Hallo, Lebende. Ich brauche gerade etwas, was es whahrscheinlich nicht gibt, geschweigedenn in
    irgend einem Tutorial zu finden ist. Aber vielleicht ist es doch machbar und jemand hier weiß wie.

    Ich habe eine Tabelle 'categories'

    Quellcode

    1. CREATE TABLE `categories` (
    2. `id` int(11) NOT NULL default '0',
    3. `sub` int(11) NOT NULL default '0',
    4. `name` text collate latin1_general_ci NOT NULL,
    5. PRIMARY KEY (`id`)
    6. ) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_general_ci;
    7. INSERT INTO `categories` (`id`, `sub`, `name`) VALUES
    8. (1, 0, 'Bücher'),
    9. (2, 1, 'Romane'),
    10. (3, 1, 'Biografien'),
    11. (4, 1, 'Geistiger Abfall'),
    12. (5, 2, 'Krimis');
    Alles anzeigen


    Und brauche eine Möglichkeit, die 3 Zeilen 'Bücher', 'Romane' und 'Krimis' geliefert zu bekommen.
    Dabei geht es darum, via sql die ganze Unterordnungsstange bis zu Krimis abzufragen.
    Mit einer Rückverfolgungsschleife ist es leicht möglich, jedenfalls gibt es ab einer Kategorisierung
    von 10 subordinierenden Items halt 10 hintereinanderfolgende Datenbankanfragen.
    Geht es nicht mit weniger Verkehr?

    Hoffe, hier eine Antwort auf mein Problem zu finden.
    Bedanke mich.
  • Ich will ja nicht den ganzen Baumstamm ab einer Zeile bzw ab der ganzen Wurzel haben.
    Ich will anhand einer Zeile den Strang zurückverfolgen. Über dem liegt das, über
    dem liegt das und darüber das. Und diese ganzen Zeilen, die drüber liegen in passender
    Reihenfolge gesendet haben.

    Das Beispiel von Wikipedia vrstehe ich im übrigen nicht

    Quellcode

    1. SELECT (COUNT(parent.id)-1) AS depth, node.id
    2. FROM tree AS node, tree AS parent
    3. WHERE node.l BETWEEN parent.l and parent.r
    4. GROUP BY node.id ORDER BY node.l;

    Hast du vll. eine resource parat, die das erklärt?
    Ja, ich benutze MySQL und nicht postgree oder sonst was.
    Wird halt am häufigsten verwendet.

    SELECT (COUNT(parent.id)-1) AS depth, node.id
    FROM categories AS node, categories AS parent
    WHERE node.l BETWEEN parent.l and parent.r
    GROUP BY node.id ORDER BY node.l

    so klappt das schonmal nicht und ich glaube, dieser
    query ist für mysql geeignet.

    // edit
    Ich glaub, ich hab da was
    php-resource.de/tutorials/read/21/2/

    Dieser Beitrag wurde bereits 2 mal editiert, zuletzt von sjBlack ()

  • Nein. Aber den Strang muss man doch irgendwie mit einem simplen SQL query
    bei einer MySQL Datenbank abfragen können?
    Das Skript, für das ich das brauche, muss möglichst Hostunabhängig sein.
    Ich will die Einträge mit einer Id und einer sub-Spalte.

    Wie ich den ganzen Baum abfragen kann, würde ich eventuell auch gerne wissen, aber:
    Ihre Subordinierung soll nicht durch eine Nummerierung wie in dem Beispiel, das ich fand, erkannt werden.
    Und die Sortierung in seiner Ebene durch eine pos-Spalte durch ORDER BY.

    In erster Linie interessiert mich nur der Strang der Eltern-"Elemente".
    Verflucht, das muss doch irgendwie simple machbar sein!
    Dann verwende ich halt eine Schleife mit einer Anfrage pro Durchlauf...

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von sjBlack ()

  • Ja, Nested Sets sind anstrengend. Das bestreitet keiner *g*

    Willst du dein DB Layout behalten, musst du es auf x Ebenen begrenzen. Z.B. so

    Quellcode

    1. SELECT * FROM categories A
    2. LEFT JOIN categories B ON B.id = A.sub
    3. LEFT JOIN categories C ON C.id = B.sub
    4. LEFT JOIN categories D ON D.id = C.sub
    5. LEFT JOIN categories E ON D.id = E.sub
    6. WHERE A.id = 5;
  • Das ist so hoffnungslos. Ich bekomem es nichteinmal hin, wenn ich es auf 3 Ebenen begrenze.
    Jetzt habe ich das Problem wieder in einer Boardsoftware.

    Quellcode

    1. CREATE TABLE `sj_forums` (
    2. `id` int(10) unsigned NOT NULL default '0',
    3. `sub` int(11) NOT NULL default '0',
    4. `pos` int(11) NOT NULL default '0',
    5. `list_subforums` tinyint(1) NOT NULL default '1',
    6. `list_topics` tinyint(1) NOT NULL default '1',
    7. `stat_topics` int(10) unsigned NOT NULL default '0',
    8. `stat_posts` int(10) unsigned NOT NULL default '0',
    9. `title` text collate latin1_general_ci NOT NULL,
    10. `desc` text collate latin1_general_ci NOT NULL,
    11. PRIMARY KEY (`id`)
    12. ) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_general_ci;
    Alles anzeigen


    sub ist der Vaterzeiger auf das übergeordnete Forum.
    stat_topics beinhaltet die Anzahl der Themen, die sich
    in dem Forum befinden. Relativ, nicht absolut!

    Nun versuche ich die ids der Foren eins unter dem Forum der id 0 (wurzelforum)
    aufzulisten mit der Anzahl der Themen in absoluter Tiefe abzurufen.

    SELECT `id`, SUM(`stat_topics`) AS `sum_stat_topics`, SUM(`stat_posts`) AS `sum_stat_posts`
    FROM `sj_forums` A
    LEFT JOIN `sj_forums` B ON B.id = A.sub
    LEFT JOIN `sj_forums` C ON C.id = B.sub
    WHERE A.`sub`=0
    GROUP BY `id`

    MySQL meldet: Dokumentation
    #1052 - Column 'id' in field list is ambiguous

    Selbst das bekomme ich nicht hin!
    H-E-L-P!!!
  • SQL-Abfrage

    1. SELECT
    2. A.`id` AS `id`,
    3. SUM(`stat_topics`) AS `sum_stat_topics`,
    4. SUM(`stat_posts`) AS `sum_stat_posts`
    5. FROM `sj_forums` A
    6. LEFT JOIN `sj_forums` B ON B.id = A.sub
    7. LEFT JOIN `sj_forums` C ON C.id = B.sub
    8. WHERE A.`sub`=0
    9. GROUP BY `id`

    #1052 - Column 'stat_topics' in field list is ambiguous


    Ich fasse mein Problem mal so...

    Ich habe eine Tabelle categories, wo jede Zeile eine Kategorie darstellt.
    Eine Kategorie kann in einer anderen geschachtelt sein.
    Jede Kategorie hat eine eindeutige id und eine sub-Spalte, welche angibt,
    welcher übergeordneten Kategorie sie unetrgeordnet ist (Vaterzeiger).

    Außerdem sind da noch die 2 Spalten 'title', 'text' und 'hits'.
    In text ist halt der Text, den man sich anschaut.
    hits gibt an, wie oft die ejweilige Kategorie gelesen wurde.

    Die Wurzelkategorie hat die id 0 und sub -1.
    Nun möchte ich alle Kategorien mit ihrer id abrufen und der absoluten
    Anzahl der hits, die der Kategorie der id 0 (Wurzelkategorie)
    untergeordnet sind. In einer Gruppierung halt, mit SUM() etc.

    Unter absolute Anzahl meine ich die Summe aus der
    hits-Spalte einer aufgelisteten Unterkategorie und
    denen, die dieser untergeordnet sind.

    Der Baum kann auf 3 Ebenen begrenzt sein.
    Dann müsste das mit JOINS irgendwie zu machen sein.
    Nur weiß ich halt nicht, wie..

    So klappt das schonmal nicht:

    SQL-Abfrage

    1. SELECT `id`, SUM(B.`hits`)
    2. FROM `categories` A, `categories` B, `categories` C
    3. WHERE A.`sub`=0
    4. LEFT JOIN B.`sub`=A.`id`
    5. LEFT JOIN C.`sub`=B.`id`
    6. GROUP BY `id`


    #1064 - You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'LEFT JOIN B. `sub` = A. `id` LEFT JOIN C. `sub` = B. `id` GROUP BY `id`
    LIMI' at line 1


    Brainfuck-Quellcode

    1. -- phpMyAdmin SQL Dump
    2. -- version 2.11.1
    3. -- http://www.phpmyadmin.net
    4. --
    5. -- Host: localhost
    6. -- Erstellungszeit: 25. Dezember 2007 um 23:59
    7. -- Server Version: 5.0.45
    8. -- PHP-Version: 5.2.4
    9. SET SQL_MODE="NO_AUTO_VALUE_ON_ZERO";
    10. --
    11. -- Datenbank: `test`
    12. --
    13. -- --------------------------------------------------------
    14. --
    15. -- Tabellenstruktur für Tabelle `categories`
    16. --
    17. CREATE TABLE `categories` (
    18. `id` int(10) unsigned NOT NULL auto_increment,
    19. `sub` int(11) NOT NULL default '0',
    20. `hits` int(10) unsigned NOT NULL default '0',
    21. `title` text collate latin1_general_ci NOT NULL,
    22. `text` text collate latin1_general_ci NOT NULL,
    23. PRIMARY KEY (`id`)
    24. ) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_general_ci AUTO_INCREMENT=3 ;
    25. --
    26. -- Daten für Tabelle `categories`
    27. --
    28. INSERT INTO `categories` (`id`, `sub`, `hits`, `title`, `text`) VALUES
    29. (1, 0, 0, 'Spielen nach Noten', 'Wenn sie bla bla können sie hier ja weitermachen\r\nhier das bla bla usw...'),
    30. (0, -1, 0, 'Gitarrenkurs für Anfänger', 'Hier bla bla Gitarren bla\r\nFahren sie fort mit Spielen nach Noten bla\r\nwenn bla'),
    31. (2, 0, 0, 'Spielen nach Gefühl', 'Ich muss euch ab hier enttäuschen.\r\nIch bin ein lügner, ich kann selbst nicht Gitarre spielen...');
    Alles anzeigen



    Das hier funtkioniert mit der Ebenenbegrenzung, die ich leider in Kauf nehmen muss.

    SQL-Abfrage

    1. SELECT
    2. A.id AS `id`,
    3. A.title AS `title`,
    4. SUM(A.stat_posts) + SUM(B.stat_posts) + SUM(C.stat_posts) AS `sum_stat_posts`
    5. FROM `sj_forums` A, `sj_forums` B, `sj_forums` C
    6. WHERE A.sub=0 AND B.sub=A.id AND C.sub=B.id
    7. GROUP BY A.id

    Leider aber auch nur auf Unterforen, die selbst mindestens 2 Unterforen haben!

    Dieser Beitrag wurde bereits 2 mal editiert, zuletzt von sjBlack ()

  • AHAHAHAHAHAHA UHIHIHIHI

    UHIHIHIHIHIHIHIHIIH ICH HABS GESCHAFFT

    UNGLAUBLICH DASS DIESER QUERY FUNKTIONIERT


    SQL-Abfrage

    1. SELECT
    2. `id`, SUM(`stat_posts`) + (
    3. SELECT SUM(`stat_posts`) FROM `sj_forums` A WHERE A.`sub`=Z.id
    4. ) AS `sum_stat_posts`
    5. FROM `sj_forums` Z WHERE `sub`=0
    6. GROUP BY `id`


    nochn paar einschübe udn ich schaff an die 10 ebenen!!!
    UHIHIHI

    // edit
    VERDAMMTE SCHEISSE!!!
    Wenn ich jetzt nichts finde, was NULL in 0 konvertiert, war auch das ein Fehlschlag!

    SQL-Abfrage

    1. SELECT
    2. `id`, SUM(`stat_posts`) + (
    3. SELECT SUM(`stat_posts`) FROM `sj_forums` A WHERE A.`sub`=Z.`id`
    4. ) AS `absstat_posts`
    5. FROM `sj_forums` Z
    6. WHERE `sub`=1
    7. GROUP BY `id`;

    Ich bekomme hier 2x NULL ausgegeben, weil 2 Unterkathegorien keine weiteren Unterkathegorien beinhalten...
    Und irgendwas + NULL ist NULL...


    SQL-Abfrage

    1. SELECT
    2. `id`, SUM(`stat_posts`) + (IFNULL(
    3. SELECT SUM(`stat_posts`) FROM `sj_forums` A WHERE A.`sub`=Z.`id`
    4. ), 0) AS `absstat_posts`
    5. FROM `sj_forums` Z
    6. WHERE `sub`=1
    7. GROUP BY `id`


    #1064 - You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'SELECT SUM( `stat_posts` ) FROM `sj_forums` A WHERE A. `sub` = Z. `id` ) , 0 ) ' at line 1

    WHYYYYYYYYYYYYY!?!?!?!?!?!?
    WHYYYYYYYYYYYYYYYYYYYYY!?!?!!?
    ICH WAR SO NAH DRAN ;( SO VERDAMMT NAH DRAN ;X; ;( ;( ;(

    DIESE GOTTVERDAMMTE NULL!!!

    Dieser Beitrag wurde bereits 3 mal editiert, zuletzt von sjBlack ()

  • ich würd ja in der Datenbank alle NULL Werte durch 0 ersetzen. - am besten du ergänzt im Schema einfach ein NOT NULL.
    Sonst wird dein SQL Query nur unnötig droß.

    btw: Auch wenn man hier für dein Problem nichts nützliches findest, es gibt sogar eine eigene Dokuseite für Probleme mit NULL ;)
    dev.mysql.com/doc/refman/5.1/de/problems-with-null.html