veraltete Referenzen finden.

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

  • veraltete Referenzen finden.

    Hallo,

    ich stehe grade total auf dem Schlauch wg. eines vermutlich
    sehr trivialen Problems. Ich will veraltete Referenzen aus
    einer Datenbank entfernen, bzw. zuerst mal finden.
    Das ganze ist in EINER Tabelle:
    • id | parent
      ------------
      01 | 00
      02 | 01
      04 | 03
      05 | 01


    "id" ist der index, "parent" ist die Referenz auf ein übergeordnetes Element
    ähnlich einer Baumstruktur. Nun kann es sein, dass das übergeordnete Element nicht mehr existert - wie hier "03".
    Ich suche nun den SQL-String, der mir als Ergebnis den Datensatz "04" liefern würde. Bin wohl zu dumm!

    Habe schon es mit Joins versucht a la
    Code:
    SELECT t1.id FROM TABELLE t1 INNER JOIN TABELLE t2 ON t1.id=t2.id WHERE t2.parent != t1.id
    was aber Unsinn ist und nicht funktioniert.
    Gruss,
    Stefan

  • #2
    Schau dir mal die Subselects an
    ala : select * from x where id not in (select * from yyyy where xxx)

    *war doch so... *

    php-Entwicklung | ebiz-consult.de
    PHP-Webhosting für PHP Entwickler | ebiz-webhosting.de
    die PHP Marktplatz-Software | ebiz-trader.de

    Comment


    • #3
      Originally posted by Berni View Post
      *war doch so... *
      war auch so

      Danke! So ging es!

      so sieht in meinem fall der richtige SQL String aus:
      (auch wenn das ausser mir wohl keinem hilft)
      $sql = 'SELECT * FROM `pcm_pages` WHERE page_parent NOT IN (SELECT page_id FROM `pcm_pages` WHERE 1) AND page_parent != 0';
      Gruss,
      Stefan

      Comment


      • #4
        hey! ich kann noch SQL!

        php-Entwicklung | ebiz-consult.de
        PHP-Webhosting für PHP Entwickler | ebiz-webhosting.de
        die PHP Marktplatz-Software | ebiz-trader.de

        Comment


        • #5
          Ich auch:
          Code:
          SELECT a.page_id AS haengender_knoten
            FROM `pcm_pages` AS a
            LEFT OUTER JOIN `pcm_pages` AS b
           ON a.page_parent = b.page_id
            WHERE b.page_id IS NULL AND a.page_parent <> 0
          Wir werden alle sterben

          Comment


          • #6
            Ich finde combie's Lösung attaktiver. ;-)
            INFO: Erst suchen, dann posten![color=red] | [/color]MANUAL(s): PHP | MySQL | HTML/JS/CSS[color=red] | [/color]NICE: GNOME Do | TESTS: Gästebuch[color=red] | [/color]IM: Jabber.org |


            Comment


            • #7
              ich auch

              php-Entwicklung | ebiz-consult.de
              PHP-Webhosting für PHP Entwickler | ebiz-webhosting.de
              die PHP Marktplatz-Software | ebiz-trader.de

              Comment


              • #8
                Danke für die Blumen.

                Aber:
                1. überlassen wir mal dem EXPLAIN, welche die schönere Abfrage ist.
                2. ist das Problem schon unmöglich!

                In einem Baum darf es keine einsam in der Luft hängenden Äste geben. Auch muß rekursiv gelöscht werden, es gibt ja evtl.noch Unteräste

                Das erledigt diese Struktur:
                Code:
                CREATE TABLE IF NOT EXISTS `baum` (
                  `id` int(11) NOT NULL AUTO_INCREMENT,
                  `parent` int(11) DEFAULT NULL,
                  `name` varchar(255) NOT NULL,
                  PRIMARY KEY (`id`),
                  KEY `parent` (`parent`)
                ) ENGINE=InnoDB  DEFAULT CHARSET=latin1 AUTO_INCREMENT=0 ;
                
                ALTER TABLE `baum`
                  ADD CONSTRAINT `baum_ibfk_1` FOREIGN KEY (`parent`) REFERENCES `baum` (`id`) ON DELETE CASCADE;
                Wir werden alle sterben

                Comment


                • #9
                  Das ist korrekt. Aber das ist Beyond vermutlich egal.
                  INFO: Erst suchen, dann posten![color=red] | [/color]MANUAL(s): PHP | MySQL | HTML/JS/CSS[color=red] | [/color]NICE: GNOME Do | TESTS: Gästebuch[color=red] | [/color]IM: Jabber.org |


                  Comment


                  • #10
                    Originally posted by Abraxax View Post
                    Das ist korrekt. Aber das ist Beyond vermutlich egal.
                    Ist es natürlich NICHT
                    Allerdings gebe ich zu, ich werde noch ein paar Monate benötigen, um
                    die Routine von combie ansatzweise zu verstehen.

                    Code:
                    ALTER TABLE `baum`
                      ADD CONSTRAINT `baum_ibfk_1` FOREIGN KEY (`parent`) REFERENCES `baum` (`id`) ON DELETE CASCADE;
                    bedeutet wohl, dass er bei Löschvorgängen auch die Unteräste löscht?

                    Das ganze brauche ich für ein Content Management System (das ca. 5000te mittlerweile). Meine "Baumstruktur" habe ich mir selber zusammengeschustert.
                    PHP Code:
                                  $sql=    "CREATE TABLE "TABLE_PAGES ." (
                                    page_id int(11) NOT NULL auto_increme
                                  page_parent int(11) NOT NULL default '0',
                                  page_level int(4) NOT NULL default '0',
                                  page_sort int(11) NOT NULL default '0',
                                  page_title varchar(255) NOT NULL default '',
                                    page_menu enum ('0','1') default '1',
                                  page_active enum ('0','1') default '1',
                                  PRIMARY KEY (page_id))"

                    Level=0 ist im Root. Sort ist dann die Sortierung in einer Ebene. Menu und
                    Active sind quasi nur Flags.
                    Das ganze funktioniert auch recht gut und schnell, nur hatte ich einen
                    Fehler nicht abgefangen, der mir dann Bäume nicht rekursiv gelöscht hatte
                    und deshalb dieser Fehler zustande kam.

                    Edit:
                    Bin doch dabei es eher zu verstehen, dank dieser Seite (Punkt 5.4.5 ff):
                    http://www.postgresql.org/files/docu...nstraints.html
                    Last edited by Beyond; 23-06-2009, 08:37.
                    Gruss,
                    Stefan

                    Comment


                    • #11
                      ich werde noch ein paar Monate benötigen
                      Ist auch nur mit Wasser gekocht...


                      bedeutet wohl, dass er bei Löschvorgängen auch die Unteräste löscht?
                      Genau!

                      Ein paar Kleinigkeiten fallen mir da noch auf:
                      page_parent int(11) NOT NULL default '0',
                      Da es kein Element mit der ID 0 geben darf/kann ist default 0 nicht unbedingt angemessen. NULL (kein Vorgänger) wäre logischer als 0(ungültige ID)

                      page_level int(4) NOT NULL default '0',
                      Level ist doch sicher die Rekursionstiefe, oder?
                      Diese ergibt sich allerdings automatisch, gehört also zu den redundanten Daten. Das führt zu Mehraufwand(Sorgen) beim Verlegen der Äste.

                      Und hier mal ein "schlankes" JOIN Tutorial: Coding Horror: A Visual Explanation of SQL Joins
                      Wir werden alle sterben

                      Comment


                      • #12
                        Originally posted by combie View Post
                        Da es kein Element mit der ID 0 geben darf/kann ist default 0 nicht unbedingt angemessen. NULL (kein Vorgänger) wäre logischer als 0(ungültige ID)
                        Stimmt. Allerdings ist die 0 bei PHP ganz prakisch, weil sie als Boolean FALSE dienen kann. Ist aber wohl bei NULL auch so, oder?

                        Originally posted by combie View Post
                        Level ist doch sicher die Rekursionstiefe, oder?
                        Diese ergibt sich allerdings automatisch, gehört also zu den redundanten Daten. Das führt zu Mehraufwand(Sorgen) beim Verlegen der Äste.
                        Stimmt. Da ich den Level auch für die grafische Darstellung benötige, dachte ich es ist schneller diesen einmal beim Hinzufügen eines Astes in der DB zu speichern, als diesen bei jedem Aufruf zu ermitteln.
                        Habe ausserdem keine Ahnung wie ich diesen schnell aus Deiner Struktur (die übrigens vortrefflich rekursiv löscht, habs auspropiert) die Tiefe ermittle, ausser vielleicht so:
                        PHP Code:
                        // aktuelles element = $page_id
                        $level 0;
                        $sql "SELECT page_parent FROM "TABLE_PAGES" WHERE page_id=$page_id";
                        $res $db->query($sql);
                          while (
                        $rows mysql_fetch_array($res))
                            {
                            
                        $page_id $rows['page_id'];
                            
                        $sql2 "SELECT page_parent FROM "TABLE_PAGES" WHERE page_id=$page_id";
                            
                        $res $db->query($sql2);
                            
                        $level ++;
                            } 
                        Originally posted by combie View Post
                        Und hier mal ein "schlankes" JOIN Tutorial: Coding Horror: A Visual Explanation of SQL Joins
                        Danke! Gut gemacht.
                        Gruss,
                        Stefan

                        Comment


                        • #13
                          Da ich den Level auch für die grafische Darstellung benötige,
                          Du brauchst für die Darstellung sicherlich noch mehr Daten, als nur die Tiefe. Also mußt du dich sowieso den Baum entlang hangeln. Dabei kannst du das Tiefen Problem gleich mit erledigen.

                          Bäume in DB Tabellen abzubilden ist immer mit "Nachteilen" verbunden. Das Parent/ID Konzept zwingt dazu, den Baum rekursiv zu durchlaufen. Das ist recht teuer.
                          "Nested Sets" sind beim Lesen billiger, weil die Rekursion quasi beim Eintragen schon vorweg genommen wurde. Wenn also hauptsächlich gelesen wird, dann sind Nested Sets günstiger.

                          Mein Favorit: Doctrine ORM for PHP - Hierarchical Data
                          Wir werden alle sterben

                          Comment

                          Working...
                          X