veraltete Referenzen finden.

Einklappen
X
 
  • Filter
  • Zeit
  • Anzeigen
Alles löschen
neue Beiträge

  • 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

    Kommentar


    • #3
      Zitat von Berni Beitrag anzeigen
      *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

      Kommentar


      • #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

        Kommentar


        • #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

          Kommentar


          • #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 |


            Kommentar


            • #7
              ich auch

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

              Kommentar


              • #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

                Kommentar


                • #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 |


                  Kommentar


                  • #10
                    Zitat von Abraxax Beitrag anzeigen
                    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
                    Zuletzt geändert von Beyond; 23.06.2009, 09:37.
                    Gruss,
                    Stefan

                    Kommentar


                    • #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

                      Kommentar


                      • #12
                        Zitat von combie Beitrag anzeigen
                        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?

                        Zitat von combie Beitrag anzeigen
                        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 ++;
                            } 
                        Zitat von combie Beitrag anzeigen
                        Und hier mal ein "schlankes" JOIN Tutorial: Coding Horror: A Visual Explanation of SQL Joins
                        Danke! Gut gemacht.
                        Gruss,
                        Stefan

                        Kommentar


                        • #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

                          Kommentar

                          Lädt...
                          X