Sql schleife, subselect oder join oder doch was anderes?

Dieses Thema im Forum "Webentwicklung" wurde erstellt von Decryptor, 21. Dezember 2014 .

Schlagworte:
  1. Diese Seite verwendet Cookies. Wenn du dich weiterhin auf dieser Seite aufhältst, akzeptierst du unseren Einsatz von Cookies. Weitere Informationen
  1. Decryptor
    Decryptor Psychopath
    Stammnutzer
    #1 21. Dezember 2014
    Hallo,
    ich habe im moment ein kleines Problem was doch etwas über meine Vorstellungskraft geht.

    ich habe eine DB die so aufgebaut ist
    [​IMG]


    jedes Forum egal ob Main oder Sub hat eine eindeutige ID, und parent ID,
    die parent Id wenn Sie nicht 0 ist enthält die Id des über geordneten und dies setzt sich soweit fort bis zu einer bestimmten ID 14 als bsp bei der soll es nichtmehr weiter gehen.

    Ich bräuchte nun eine Ausgabe die die Ursprungsid enthält aber alle Namen der jeweiligen Namen


    also als bsp

    6 -> Haupt->Hauprsub_a->Sub_a->Subsub

    hatte das ganze per php rekrusiv per Schleife die ich irgendwan abgebrochen hab machen lassen dies ist aber nicht die beste lössung zumal unflexibel wenn sich irgend etwas ändert also muss ne sql lössung her, ich nutzte mysql, ich habe aber hierbei irgendwie keinen plan
     

  2. Anzeige
  3. raid-rush
    raid-rush Admin
    Administrator
    #2 21. Dezember 2014
    AW: Sql schleife, subselect oder join oder doch was anderes?

    ich würde einen query machen und einfach die relativ kleine datenmenge in ein array laden und dann dort abarbeiten. die art von ausgabe die du willst ist mit einem query nicht sinnvoll lösbar.
     
  4. Decryptor
    Decryptor Psychopath
    Stammnutzer
    #3 21. Dezember 2014
    AW: Sql schleife, subselect oder join oder doch was anderes?

    naja es sind ca 300 foren die ich so verknüpfen will.
    also schlägst du mir auch wieder die php lössung vor?
     
  5. raid-rush
    raid-rush Admin
    Administrator
    #4 21. Dezember 2014
    AW: Sql schleife, subselect oder join oder doch was anderes?

    Ist trotzdem eine kleine Datenmenge die gut in ein Array passt. Ist sicher weniger Rechen- und Speicher-intensiv als viele Querys.

    Code:
    $array = fetch_assoc<--sql<--(select * from menu);
    also ein array mit der DB drin.
    
    function get_menu($id,$array,$menu=0){
    foreach($array AS $entry){if($entry[id]==$id){$next = $entry[parent_id]; $menu[] = $entry;break;}}
    if($entry[parent_id]!=0){get_menu($next,$array,$menu);}
    return $menu;
    }
    $menu = get_menu(6,$array);
    var_dump(array_reverse($menu));
    
    
    Möglicherweise mit Fehlern, aber so vom Prinzip sollte es passen.
     
  6. Murdoc
    Murdoc D'OH!
    Team
    #5 21. Dezember 2014
    AW: Sql schleife, subselect oder join oder doch was anderes?

    @raid-rush

    Dein Ansatz ist gut, deine Umsetzung hingegen ... :p
    Das kann so gar nicht funktionieren, da $menu per Wert übergeben wird (die falsche Umwandlung von 0 zu einem array mal dahin gestellt). $menu wird daher jedes mal kopiert sobald du schreibend darauf zugreifst.

    Das ganze lässt sich auch ohne Rekursion lösen:

    PHP:
    <? php

    class  Forum  {
      public 
    $id ;
      public 
    $name ;
      public 
    $menu  = [];
      public 
    $prev  null ;
        
      public function 
    __construct ( $id $name )
      {
        
    $this -> id  $id ;
        
    $this -> name  $name ;
      }
    }


    function  map_forums ( $cid  0 ) {
      
    //$pdo = new PDO(...);

      //$res = $pdo->query('
        //SELECT `ID`, `Name`, `Parent_ID`
        //FROM `Foren`
        //ORDER BY `ID` ASC, `Parent_ID` ASC
      //');
      
      
    $res  = [
        [ 
    'ID'  =>  '1' 'Name'  =>  'Haupt' 'Parent_ID'  =>  '0'  ],
        [ 
    'ID'  =>  '2' 'Name'  =>  'Hauptsub_a' 'Parent_ID'  =>  '1'  ],
        [ 
    'ID'  =>  '3' 'Name'  =>  'Hauptsub_b' 'Parent_ID'  =>  '1'  ],
        [ 
    'ID'  =>  '4' 'Name'  =>  'Sub_a' 'Parent_ID'  =>  '2'  ],
        [ 
    'ID'  =>  '5' 'Name'  =>  'Sub_a2' 'Parent_ID'  =>  '2'  ],
        [ 
    'ID'  =>  '6' 'Name'  =>  'subsub' 'Parent_ID'  =>  '4'  ]
      ];

      
    $root  = new  Forum ( '0' '<root>' );

      
    // forum maps
      
    $tbl  = [  '0'  =>  $root  ];
      
    $stk  = [];

      foreach (
    $res  as  $itm ) {
        
    $pid  $itm [ 'Parent_ID' ];
        
    $iid  $itm [ 'ID' ];
        
        if (!isset (
    $tbl [ $pid ])) {
          
    // assume that forum $pid gets defined later
          
    $stk [ $pid ] =  1 ;
          
    $tbl [ $pid ] = new  Forum ( $pid '<missing>' );
        }
        
        if (isset (
    $stk [ $iid ])) {
          
    // resolve missing link
          
    unset ( $stk [ $iid ]);
          
    $frm  $tbl [ $iid ];
          
    $frm -> name  $itm [ 'Name' ];
        } else {
          
    // create new entry
          
    $frm  = new  Forum ( $itm [ 'ID' ],  $itm [ 'Name' ]);
          
    $tbl [ $iid ] =  $frm ;
        }
        
        
    $frm -> prev  $tbl [ $pid ];
        
    $tbl [ $pid ]-> menu [] =  $frm ;
      }

      
    // if (!empty ($stk)) 
        // throw new Error('some parent-forums are missing');
      
      
    if (!isset ( $tbl [ $cid ]))
        return 
    null ;
      
      return 
    $tbl [ $cid ];
    }

    $res  map_forums ( 6 );

    if (
    $res  ===  null )
      echo 
    "forum 6 does not exists" ;
    else {
      
    $stk  = [];
      do {
        
    array_unshift ( $stk $res -> name );
        
    $res  $res -> prev ;  
      } while (
    $res  !==  null );
      
      echo 
    htmlentities ( implode ( ' --> ' $stk ));
    }

    Wie du sehen kannst, kann man mittels "->prev" den Baum nach oben wandern.
     

  7. Videos zum Thema