Paco: Zwei SQL-Querys ineinander verschachteln

Hallo!
Ich bastele weiter an meinem kleinen Projektverwaltungstool. Nachdem ich bei meinem letzten post schon Häme und Schimpfe über mein vermurkstes Datenbankdesign bekommen und dies auch eingesehen habe, habe ich alles nochmal überarbeitet. Es gibt eine Tabelle mit Usern, eine mit Projekten und -vereinfacht- eine für Disposition. In dieser stehen als Fremdschlüssel die IDs aus Projekten und Usern.

Ich möchte jetzt eine tabellarische Ausgabe erreichen, a la:

    echo '<td>Projekt</td>';  
    echo '<td>User</td>';  
    echo '<tr>';  
    echo '<td>';  
  
    $query = "SELECT * FROM projekte ORDER BY projekt";  
    $sql = mysql_query($query);  
    while ($link = mysql_fetch_object($sql))  
        {  
        $projekt = ($link -> projekt);  
        echo '</td>';  
        echo '<td>'  
        echo ***User für das Projekt $projekt***  
        echo '</td>';  
        }  
  
  
***User für das Projekt $projekt*** erhalte ich erfolgreich mittels:  
$query = "SELECT projekt, UserName  
                FROM  
                    projekte, users, dispo  
                WHERE  
                    projekte.projekt = '$projekt'  
                AND  
                    projekte.id = dispo.pr_id  
                AND  
                    users.UserID = dispo.user_id  
                ORDER BY  
                    UserName  
                ";

Aber ich bring die beiden Abfragen einfach nicht zusammen. Geht das nur, indem ich die Tabellen schon bei der Abfrage joine? und wenn ja, wie? Ich habe mir da schon die Zähne dran ausgebissen..
Vieln Dank im Voraus

Paco

  1. Mahlzeit Paco,

    Ich möchte jetzt eine tabellarische Ausgabe erreichen, a la:

    Was genau soll in dieser Tabelle stehen? Die User die einem oder mehreren Projekten zugeordnet sind?

    Dann solltest Du diese Information auch daher ziehen, wo sie drinstehen - nämlich aus der Tabelle "dispo".

    ***User für das Projekt $projekt*** erhalte ich erfolgreich mittels:

    Du setzt also innerhalb einer Schleife für jeden Durchgang eine SQL-Abfrage ab, um die jeweiligen Benutzer auszulesen?

    Aber ich bring die beiden Abfragen einfach nicht zusammen. Geht das nur, indem ich die Tabellen schon bei der Abfrage joine?

    Nein, nicht nur. Aber sinnvollerweise solltest Du das genau so machen.

    und wenn ja, wie? Ich habe mir da schon die Zähne dran ausgebissen..

    Dabei hilft SELFHTML. Was genau hast Du bisher versucht?

    MfG,
    EKKi

    --
    sh:( fo:| ch:? rl:( br:> n4:~ ie:% mo:} va:) de:] zu:) fl:{ ss:) ls:& js:|
    1. Hallo Ekki! Danke für die schnelle Antwort!

      Was genau soll in dieser Tabelle stehen? Die User die einem oder mehreren Projekten zugeordnet sind?

      Beides. Zunächst sollen da die Projekte mit den jeweils zugeordneten Usern stehen, aber bei Bedarf möchte ich auch alle User auflisten können, mit den Projekten für die sie disponiert sind

      Dann solltest Du diese Information auch daher ziehen, wo sie drinstehen - nämlich aus der Tabelle "dispo".

      Das leuchtet mir ein, allerdings kann es projekte geben, für die noch niemand disponiert wurde und die dann in dispo nicht auftauchen

      Du setzt also innerhalb einer Schleife für jeden Durchgang eine SQL-Abfrage ab, um die jeweiligen Benutzer auszulesen?

      ..und die so ermittelten dann wieder in einer schleife auszugeben. Wenn das geht würde ich das gerne so machen

      Nein, nicht nur. Aber sinnvollerweise solltest Du das genau so machen.

      Hat das nur performance-vorteile oder auch andere? Ginge das auch mit subqueries?

      Was hast Du bisher versucht?

      Sowas wie:
      SELECT * FROM projekte LEFT JOIN dispo ON projekte.id = dispo.pr_id
      JOIN users ON dispo.user_id = users.id

      Ich glaube die Abfrage hat mir auch das richtige Array geliefert, aber ich tu mich irrsinnig schwer das Array, das ich dann bekomme, vernünftig sortiert auszugeben. Deswegen dachte ich, ich mach die Abfrage mehr oder weniger direkt in der jeweiligen Tabellenzelle.

      MfG,
      EKKi

      1. Mahlzeit Paco,

        Dann solltest Du diese Information auch daher ziehen, wo sie drinstehen - nämlich aus der Tabelle "dispo".
        Das leuchtet mir ein, allerdings kann es projekte geben, für die noch niemand disponiert wurde und die dann in dispo nicht auftauchen

        Macht nichts - wenn Du die Tabellen richtig verknüpfst. Hast Du Dir den verlinkten Artikel zum Thema JOINs durchgelesen?

        Du setzt also innerhalb einer Schleife für jeden Durchgang eine SQL-Abfrage ab, um die jeweiligen Benutzer auszulesen?
        ..und die so ermittelten dann wieder in einer schleife auszugeben. Wenn das geht würde ich das gerne so machen

        Das geht, ist aber ziemlicher Mist. Für Abfragen ist das DBMS da, nicht irgendwelche Programmiersprachen ... :-)

        Nein, nicht nur. Aber sinnvollerweise solltest Du das genau so machen.
        Hat das nur performance-vorteile oder auch andere? Ginge das auch mit subqueries?

        Es hat in der Tat hauptsächlich Performance-Vorteile. Und es geht auch mit Subqueries, wenn Dein DBMS das unterstützt. Da Du verschwiegen hast, welches Du verwendest, müsstest Du das also herausfinden.

        Was hast Du bisher versucht?
        Sowas wie:
        SELECT * FROM projekte LEFT JOIN dispo ON projekte.id = dispo.pr_id
        JOIN users ON dispo.user_id = users.id

        Das sieht doch prinzipiell gar nicht so schlecht aus. Allerdings solltest Du Dir wirklich den verlinkten Artikel zu JOINs zu Gemüte führen. Insbesondere würde ich die Tabelle "users" auch mittels einem LEFT (OUTER) JOIN anknüpfen, da es schließlich sein kann, dass (noch) keine Benutzer zugeordnet wurden.

        Ich glaube die Abfrage hat mir auch das richtige Array geliefert,

        Eine Abfrage liefert kein Array zurück, sondern eine Ergebnismenge. Was dann die verwendete Programmiersprache daraus macht, ist der Sprache bzw. dem Programmierer überlassen. Was bedeutet "du glaubst"? Hast Du Dir einfach mal mittels print_r() ausgeben lassen, was das Ergebnis war?

        aber ich tu mich irrsinnig schwer das Array, das ich dann bekomme, vernünftig sortiert auszugeben.

        Für das Sortieren ist das DBMS zuständig. Die Programmiersprache sollte dann (eigentlich) nur noch Zeile für Zeile untereinander schreiben.

        Deswegen dachte ich, ich mach die Abfrage mehr oder weniger direkt in der jeweiligen Tabellenzelle.

        Mit Verlaub, das ist wirklich Blödsinn. Erstens kann ein DBMS Dir viel komfortabler und schneller die gewünschten Informationen liefern und zweitens ist eine einzige Schleife für das Durchlaufen und Ausgeben der Ergebnismenge in JEDER Programmiersprache schneller als mehrere Abfragen, die jeweils nur einen einzelnen Datensatz holen.

        MfG,
        EKKi

        --
        sh:( fo:| ch:? rl:( br:> n4:~ ie:% mo:} va:) de:] zu:) fl:{ ss:) ls:& js:|
        1. Macht nichts - wenn Du die Tabellen richtig verknüpfst. Hast Du Dir den verlinkten Artikel zum Thema JOINs durchgelesen?

          Ja das habe ich gestern schon, habs auch eigentlich verstanden, mein Problem ist eher mit der Ergebnismenge umzugehen.

          Das geht, ist aber ziemlicher Mist. Für Abfragen ist das DBMS da, nicht irgendwelche Programmiersprachen ... :-)

          ok

          Es hat in der Tat hauptsächlich Performance-Vorteile. Und es geht auch mit Subqueries, wenn Dein DBMS das unterstützt. Da Du verschwiegen hast, welches Du verwendest, müsstest Du das also herausfinden.

          Performance ist nicht so wichtig, läuft alles abteilungsintern auf einem XAMPP-Apache. Aber ich möchts ja gerne richtig machen.

          Das sieht doch prinzipiell gar nicht so schlecht aus. Allerdings solltest Du Dir wirklich den verlinkten Artikel zu JOINs zu Gemüte führen. Insbesondere würde ich die Tabelle "users" auch mittels einem LEFT (OUTER) JOIN anknüpfen, da es schließlich sein kann, dass (noch) keine Benutzer zugeordnet wurden.

          Ja stimmt, das hatte ich auch gemacht.

          Eine Abfrage liefert kein Array zurück, sondern eine Ergebnismenge. Was dann die verwendete Programmiersprache daraus macht, ist der Sprache bzw. dem Programmierer überlassen. Was bedeutet "du glaubst"? Hast Du Dir einfach mal mittels print_r() ausgeben lassen, was das Ergebnis war?

          Ja, das habe ich. Und das Array hatte ich selber aus der Ergebnismenge gebildet. So:
              while ($row = mysql_fetch_assoc($sql))
                  {
                      $alles[] = $row;
                  }
          'Ich glaube', weil ich den Code nicht mehr habe. Aber print_r hat mir auf jeden Fall ein vernünftiges Ergebnis geliefert, bin dann aber nicht weiter gekommen mit dem sortieren.

          Für das Sortieren ist das DBMS zuständig. Die Programmiersprache sollte dann (eigentlich) nur noch Zeile für Zeile untereinander schreiben.

          Ja, das seh ich ja auch so. Aber das Prinzip wie ich in der ersten schleife die Projekte abarbeite und dann für jedes Projekt die User mittels einer weiteren Schleife will mir nicht in den Schädel.

          Mit Verlaub, das ist wirklich Blödsinn. Erstens kann ein DBMS Dir viel komfortabler und schneller die gewünschten Informationen liefern und zweitens ist eine einzige Schleife für das Durchlaufen und Ausgeben der Ergebnismenge in JEDER Programmiersprache schneller als mehrere Abfragen, die jeweils nur einen einzelnen Datensatz holen.

          Bisher bin ich soweit:

          $query = "SELECT projekt, UserName  
                      FROM  
                          projekte  
                      LEFT JOIN  
                          dispo_tec  
                      ON  
                          projekte.projekt = dispo_tec.pr_id  
                      LEFT JOIN  
                          users  
                      ON  
                          dispo_tec.user_id = users.UserID  
                      ";  
          $sql = mysql_query($query) or die(mysql_error());  
              while ($row = mysql_fetch_assoc($sql))  
                  {  
                      $alles[] = $row;  
                  }  
          echo '<pre>';  
          print_r($alles);  
          echo '</pre>';
          

          Bekomme aber ein leeres Array zurück :-(

          1. Berichtigung:
            print_r liefert:

            Array
            (
                [0] => Array
                    (
                        [projekt] => projekt1
                        [UserName] =>
                    )

            [1] => Array
                    (
                        [projekt] => projekt2
                        [UserName] =>
                    )

            [2] => Array
                    (
                        [projekt] => projekt3
                        [UserName] =>
                    )
            ...

            1. Mahlzeit Paco,

              Berichtigung:
              print_r liefert:

              Aha, also hast Du grundsätzlich ein Ergebnis.

              Array
              (
                  [0] => Array
                      (
                          [projekt] => projekt1
                          [UserName] =>
                      )

              Es sieht allerdings so aus, dass anscheinend keine Benutzer zugeordnet wären. Hast Du die Abfrage mal direkt auf der Konsole Deines Datenbanksystems (welches war das noch gleich???) eingegeben - oder hast Du eine entsprechende Weboberfläche zur Verfügung? Was erhältst Du als Ergebnis?

              Wie wär's, wenn Du alternativ mal einige Beispielzeilen Deiner Inhalte zur Verfügung stellst? Bist Du sicher, dass überhaupt Benutzer zugeordnet sind?

              MfG,
              EKKi

              --
              sh:( fo:| ch:? rl:( br:> n4:~ ie:% mo:} va:) de:] zu:) fl:{ ss:) ls:& js:|
              1. Hallo EKKi,

                Wie wär's, wenn Du alternativ mal einige Beispielzeilen Deiner Inhalte zur Verfügung stellst? Bist Du sicher, dass überhaupt Benutzer zugeordnet sind?

                Der Apache ist Server Version: 5.0.45.
                Ja, ich bin mir sicher, dass Benutzer zugeordnet sind. Wenn ich die Abfrage so mache:

                    $query = "SELECT projekt, UserName FROM  
                                    projekte, users, $gewerk  
                                WHERE  
                                    projekte.projekt = '$projekt'  
                                AND  
                                    projekte.id = $gewerk.pr_id  
                                AND  
                                    users.UserID = $gewerk.user_id  
                                ORDER BY  
                                    UserName  
                                ";  
                  
                    $sql = mysql_query($query) or die(mysql_error());  
                    echo 'Producer fuer das Projekt <b>' . $projekt . '</b> im Bereich ' .  $gewerk . ': <br /><br />';  
                    while ($row = mysql_fetch_assoc($sql))  
                        {  
                            echo $row['UserName']."<br />\n";  
                        }
                

                ..bekomm ich auch die User raus. Was meinst du mit Beispielzeilen meiner Inhalte?

                liebe Grüße
                Paco

                1. Mahlzeit Paco,

                  Der Apache ist Server Version: 5.0.45.

                  Der Apache ist bei einem Datenbankproblem dermaßen irrelevant ... wenn Du keine Hilfe willst, sag es doch einfach. Ansonsten hättest Du vielleicht die Güte, endlich mal die von Dir verwendete Datenbank zu benennen (inkl. Version)?

                  Ja, ich bin mir sicher, dass Benutzer zugeordnet sind. Wenn ich die Abfrage so mache:

                  Kannst Du Abfragen direkt gegen die Datenbank ausführen? Ohne jedesmal ein PHP-Skript drumherum schreiben zu müssen? Das wäre für das Entwickeln extrem hilfreich - glaub's mir.

                  ..bekomm ich auch die User raus. Was meinst du mit Beispielzeilen meiner Inhalte?

                  Was steht in Deinen Tabellen?

                  MfG,
                  EKKi

                  --
                  sh:( fo:| ch:? rl:( br:> n4:~ ie:% mo:} va:) de:] zu:) fl:{ ss:) ls:& js:|
                  1. Der Apache ist bei einem Datenbankproblem dermaßen irrelevant ... wenn Du keine Hilfe willst, sag es doch einfach. Ansonsten hättest Du vielleicht die Güte, endlich mal die von Dir verwendete Datenbank zu benennen (inkl. Version)?

                    Sorry EKKi, es ist eine mySQL-Datenbank, 5.0.45-community-nt ist das, was mir phpMyAdmin ausspuckt, wenn ich SHOW VARIABLES LIKE 'version' direkt ausführe, sonst habe ich keine Versionsnummer gefunden..

                    Kannst Du Abfragen direkt gegen die Datenbank ausführen? Ohne jedesmal ein PHP-Skript drumherum schreiben zu müssen? Das wäre für das Entwickeln extrem hilfreich - glaub's mir.

                    Ich glaub dir alles, meinst du z.B. das SQL-Eingabefenster in phpmyAdmin? Das hätte ich natürlich zur Verfügung.

                    Was steht in Deinen Tabellen?

                    users:
                      -UserID
                      -UserName
                      -etc (passwort, session..)

                    projekte:
                      -id
                      -projekt (kommt wohl noch einiges zum aktuellen status dazu..)

                    dispo_tec: (für technik, äquivalent noch für grafik/content/...)
                      -pr_id (id aus 'projekte')
                      -user_id (UserID aus 'users')
                      =>hier kommen also projekte mehrfach vor

                    die dispo_tec hat z.B. Einträge von zwei Projekten mit einmal zwei und einmal drei angelegten Usern

                    Danke für deine Geduld ;-)
                    Paco

                    1. wenn ich

                      SELECT projekt, UserName  
                                  FROM  
                                      projekte  
                                  LEFT JOIN  
                                      dispo_tec  
                                  ON  
                                      projekte.projekt = dispo_tec.pr_id  
                                  LEFT JOIN  
                                      users  
                                  ON  
                                      dispo_tec.user_id = users.UserID
                      

                      direkt in phpmyAdmin ausführe listet er mir alle projekte in 'projekte' auf, UserName jeweils Null

                      1. Mahlzeit Paco,

                        SELECT projekt, UserName
                                    FROM
                                        projekte

                        Hier schreibst Du, die Tabelle heißt "projekt" - wie denn nun?

                        LEFT JOIN
                                        dispo_tec
                                    ON
                                        projekte.projekt = dispo_tec.pr_id

                        Ich würde vermuten, dass Du den JOIN vielleicht eher auf die projekte.id machen willst?

                        Ich will ja nicht altklug erscheinen, aber ich hatte bereits darauf hingewiesen: genau solche Probleme entstehen bei einer derartigen Kraut-und-Rüben-Benennung von Tabellen und Spalten. Einige Dich mit Dir selbst und sei dann konsequent!

                        MfG,
                        EKKi

                        --
                        sh:( fo:| ch:? rl:( br:> n4:~ ie:% mo:} va:) de:] zu:) fl:{ ss:) ls:& js:|
                        1. Ich würde vermuten, dass Du den JOIN vielleicht eher auf die projekte.id machen willst?

                          Oh mein Gott, du hast natürlich recht. Jetzt bekomm ich auch ein ergebnis

                          Ich will ja nicht altklug erscheinen, aber ich hatte bereits darauf hingewiesen: genau solche Probleme entstehen bei einer derartigen Kraut-und-Rüben-Benennung von Tabellen und Spalten. Einige Dich mit Dir selbst und sei dann konsequent!

                          Ich bin kompetenzmäßig noch weit davon entfernt, irgendwelche Ratschläge als altklug abzutun. Habe mal in einem Tutorial gelesen, das schwierigste am programmieren sei, sich immer vernünftige Variablennamen auszudenken und stimme dem weitgehend zu. Ich bin da echt noch zu chaotisch, aber das kommt eben von dieser learning-by-doing Herangehensweise. Hat für mein erstes PHP-mySQL-Projekt gereicht, aber jetzt muß ich mich ein bißchen besser organisieren.

                          Da aber nun meine Abfrage das gewünschte Ergebnis liefert...

                          projekt                  UserName
                          Die Sendung mit dem Dingens  Karsten
                          Die Sendung mit dem Dingens  Martin
                          Die Sendung mit dem Dingens  Panchos
                          Sendung Bla                  Panchos
                          Sendung Bla                  Tobi
                          projekt1                  NULL
                          projekt2                  NULL
                          projekt3                  NULL
                          projekt4                  NULL
                          projektXXX                  NULL

                          ...steh ich jetzt vor dem Anfangsproblem: Du sagtest, das dbms ist für die sortierung zuständig und die Programmiersprache schreibt die sortierte Ergebnismenge nur noch untereinander. Das verstehe ich. Aber besser sortieren kann man das auf dbms-seite ja gar nicht, oder? Nur, wie schreibe ich das denn in eine Tabelle, so daß das Projekt nur einmal dasteht, aber alle dazugehörigen User? Stichwort Schleife..

                          danke

                          Paco

                          1. Mahlzeit Paco,

                            Da aber nun meine Abfrage das gewünschte Ergebnis liefert...

                            Na fein! Das war dann der erste Schritt ...

                            ...steh ich jetzt vor dem Anfangsproblem: Du sagtest, das dbms ist für die sortierung zuständig und die Programmiersprache schreibt die sortierte Ergebnismenge nur noch untereinander. Das verstehe ich. Aber besser sortieren kann man das auf dbms-seite ja gar nicht, oder? Nur, wie schreibe ich das denn in eine Tabelle, so daß das Projekt nur einmal dasteht, aber alle dazugehörigen User? Stichwort Schleife..

                            ... kommen wir nun also zum nächsten. Nix Schleife. Zumindest nicht für die einzelnen User.

                            Da Du ja mittlerweile Dein DBMS genannt hast, kann ich Dir auch sagen, dass es in MySQL eine Funktion GROUP_CONCAT() gibt, die einzelne Einträge zusammenfassen kann, die normalerweise durch eine Gruppierung mittels GROUP BY "unter den Tisch fallen" würden.

                            Wie sieht es aus, wenn Du z.B. folgende Abfrage durchführst:

                            SELECT projekt  
                            ,      GROUP_CONCAT(DISTINCT UserName SEPARATOR ', ')  
                              FROM projekte  
                              LEFT JOIN dispo_tec ON projekte.id = dispo_tec.pr_id  
                              LEFT JOIN users     ON dispo_tec.user_id = users.UserID  
                             GROUP BY projekt
                            

                            MfG,
                            EKKi

                            --
                            sh:( fo:| ch:? rl:( br:> n4:~ ie:% mo:} va:) de:] zu:) fl:{ ss:) ls:& js:|
                            1. Wie sieht es aus, wenn Du z.B. folgende Abfrage durchführst:

                              SELECT projekt

                              ,      GROUP_CONCAT(DISTINCT UserName SEPARATOR ', ')
                                FROM projekte
                                LEFT JOIN dispo_tec ON projekte.id = dispo_tec.pr_id
                                LEFT JOIN users     ON dispo_tec.user_id = users.UserID
                              GROUP BY projekt

                              
                              >   
                                
                              Sieht großartig aus! Macht genau was es soll!  
                              Vielen vielen Dank soweit, ich werde jetzt erstmal meine Datenbank umbauen und einheitlich benennen.  
                              Eine frage noch, weil du ja ittlerweile schon so im Thema bist ;-) ich hatte ursprünglich eine Tabelle 'Dispo' vorgesehen, mit den Feldern projekt, projektleiter, technik, grafik, content. Dann habe ich im Normalisierungsrausch lauter einzelne Tabellen gemacht (daher auch die blöden Namen, dispo\_tec, dispo\_graf, dispo\_cont..). Macht das deiner Meinung nach Sinn, oder ist es einfacher eine (redundante) Tabelle mit den verschiedenen Aufgabenfeldern zu benutzen? Die Performance ist eher zweitrangig, auf jeden Fall will ichs mir für eine ein paar millisekunden schnellere Abfrage nicht unnötig schwer machen.  
                                
                              lg  
                                
                              Paco  
                                
                                
                              
                              
                              1. Mahlzeit Paco,

                                Eine frage noch, weil du ja ittlerweile schon so im Thema bist ;-) ich hatte ursprünglich eine Tabelle 'Dispo' vorgesehen,

                                Und was sollte die enthalten - also inhaltlich?

                                mit den Feldern projekt, projektleiter, technik, grafik, content.

                                Und was sollten diese Felder bedeuten - inhaltlich?

                                Dann habe ich im Normalisierungsrausch lauter einzelne Tabellen gemacht (daher auch die blöden Namen, dispo_tec, dispo_graf, dispo_cont..).

                                Ich denke nicht, dass das der Normalisierungsrausch war - eher was Unstrukturierteres ... ;-)

                                Macht das deiner Meinung nach Sinn, oder ist es einfacher eine (redundante) Tabelle mit den verschiedenen Aufgabenfeldern zu benutzen?

                                Redundant ist prinzipiell eher schlecht. Genauso schlecht ist es aber auch, für neue Projekte neue Tabellen anlegen zu müssen. Also beschreib mal genauer, was Du überhaupt darstellen willst.

                                Die Performance ist eher zweitrangig, auf jeden Fall will ichs mir für eine ein paar millisekunden schnellere Abfrage nicht unnötig schwer machen.

                                Performance sollte eigentlich immer zweitrangig sein - wichtiger ist die richtiger logische Verknüpfung der Daten.

                                MfG,
                                EKKi

                                --
                                sh:( fo:| ch:? rl:( br:> n4:~ ie:% mo:} va:) de:] zu:) fl:{ ss:) ls:& js:|
                                1. Eine frage noch, weil du ja ittlerweile schon so im Thema bist ;-) ich hatte ursprünglich eine Tabelle 'Dispo' vorgesehen,

                                  Und was sollte die enthalten - also inhaltlich?

                                  Als Fremdschlüssel die ProjektID und die UserID

                                  mit den Feldern projekt, projektleiter, technik, grafik, content.

                                  Und was sollten diese Felder bedeuten - inhaltlich?

                                  Also wenn ich beispielsweise den User mit der ID 3 für das Projekt mit der ID 2 für den Bereich Technik disponiere und den User mit ID 5 für grafik dann sollen eben diese Fremdschlüssel in die Tabelle dispo.

                                  z.B.
                                  id    projekt   projektleiter      technik      grafik    ...
                                  4711  2         --                 3
                                  4712  2         --                 -            5

                                  Ich denke nicht, dass das der Normalisierungsrausch war - eher was Unstrukturierteres ... ;-)

                                  Magst du recht haben, aber es ist doch schon eine Normalisierung, wenn ich die einzelnen Bereiche in eigene Tabellen auslagere.
                                  z.B.

                                  tabelle dispotechnik
                                  id    projekt   technik
                                  4711  2         3

                                  und

                                  tabelle dispografik
                                  id    projekt   technik
                                  0815  2         5

                                  Redundant ist prinzipiell eher schlecht. Genauso schlecht ist es aber auch, für neue Projekte neue Tabellen anlegen zu müssen. Also beschreib mal genauer, was Du überhaupt darstellen willst.

                                  Darstellen möchte ich dann:

                                  Projekt     Projektleiter     Technik      Grafik
                                  blabla      Hans              Peter        Klaus
                                  blubb       Jochen            Hans         Peter

                                  bzw

                                  User        Projektleiter       technik    Grafik
                                  Hans        blabla              blubb
                                  Peter                           blabla     blubb
                                  Klaus                                      blabla

                                  Je nachdem, ob man die Auslastung der User, oder den Dispo-Stand des Projektes braucht

                                  lG
                                  Paco

                                  1. Mahlzeit Paco,

                                    Eine frage noch, weil du ja ittlerweile schon so im Thema bist ;-) ich hatte ursprünglich eine Tabelle 'Dispo' vorgesehen,

                                    Und was sollte die enthalten - also inhaltlich?
                                    Als Fremdschlüssel die ProjektID und die UserID

                                    Inhaltlich - nicht technisch. Ich habe folgendes Problem: ich besitze keine funktionierende Glaskugel, kann nicht in Deinen Schädel schauen und kenne auch nicht die Anforderungen Deines Projekts.

                                    Also wenn ich beispielsweise den User mit der ID 3 für das Projekt mit der ID 2 für den Bereich Technik disponiere und den User mit ID 5 für grafik dann sollen eben diese Fremdschlüssel in die Tabelle dispo.

                                    Das heißt, Du möchtest Personen zu Projekten zuordnen - und das in verschiedenen Rollen?

                                    id    projekt   projektleiter      technik      grafik    ...
                                    4711  2         --                 3
                                    4712  2         --                 -            5

                                    Ich denke nicht, dass das der Normalisierungsrausch war - eher was Unstrukturierteres ... ;-)
                                    Magst du recht haben, aber es ist doch schon eine Normalisierung, wenn ich die einzelnen Bereiche in eigene Tabellen auslagere.

                                    Nein, ist es nicht. Normalisierung bedeutet (ugs. gesprochen), dass gleichARTIGE (nicht gleiche!) Daten in separate Tabellen ausgelagert werden, um einerseits zwar Redundanzen zu vermeiden - andererseits ist es aber auch Ziel, nicht wegen des Einfügens oder Änderns von Daten immer Tabellenstrukturen ändern zu müssen ... und das müsstest Du - so oder so:

                                    Ursprünglich: Du müsstest immer, wenn eine neue "Rolle" hinzukommt, die Tabelle "dispo" um zusätzliche Spalten erweitern.

                                    Jetzt: Du müsstest immer, wenn eine neue "Rolle" hinzukommt, eine komplett neue Tabelle anlegen.

                                    Projekt     Projektleiter     Technik      Grafik
                                    blabla      Hans              Peter        Klaus
                                    blubb       Jochen            Hans         Peter

                                    bzw

                                    User        Projektleiter       technik    Grafik
                                    Hans        blabla              blubb
                                    Peter                           blabla     blubb
                                    Klaus                                      blabla

                                    OK, dann ist meine Vermutung bzgl. der Rollen richtig. Ich würde Dir folgende Struktur vorschlagen:

                                    Projekt
                                    ID | Name   | ...
                                    ---+--------+-----
                                     1 | blabla |
                                     2 | blubb  |

                                    Benutzer
                                    ID | Name   | ...
                                    ---+--------+-----
                                     1 | Hans   |
                                     2 | Jochen |
                                     3 | Peter  |
                                     4 | Klaus  |

                                    Rolle
                                    ID | Name          | ...
                                    ---+---------------+-----
                                     1 | Projektleiter |
                                     2 | Technik       |
                                     3 | Grafik        |

                                    Dispo
                                    ID | Projekt_ID | Benutzer_ID | Rolle_ID | ...
                                    ---+------------+-------------+----------+-----
                                     1 |          1 |           1 |        1 |
                                     2 |          1 |           3 |        2 |
                                     3 |          1 |           4 |        3 |
                                     4 |          2 |           2 |        1 |
                                     5 |          2 |           1 |        2 |
                                     6 |          2 |           3 |        3 |

                                    So kannst Du zu jedem Projekt beliebig viele Benutzer in beliebigen Rollen zuordnen und mit geeigneten Abfragen jederzeit herausfinden, wer in welcher Rolle in welchem Projekt steckt und in welchem Projekt wer in welcher Rolle steckt und und und ...

                                    MfG,
                                    EKKi

                                    --
                                    sh:( fo:| ch:? rl:( br:> n4:~ ie:% mo:} va:) de:] zu:) fl:{ ss:) ls:& js:|
                    2. Mahlzeit Paco,

                      Ich glaub dir alles, meinst du z.B. das SQL-Eingabefenster in phpmyAdmin? Das hätte ich natürlich zur Verfügung.

                      Dann nutze das für die Entwicklung Deiner Abfragen - einfach solange daran herumbasteln, bis sie genau das zurückliefern, was Du haben willst. Erst dann lohnt sich der Einbau der Abfragen in Deinen PHP-Code.

                      Was steht in Deinen Tabellen?
                      users:
                      projekte:
                      dispo_tec: (für technik, äquivalent noch für grafik/content/...)

                      die dispo_tec hat z.B. Einträge von zwei Projekten mit einmal zwei und einmal drei angelegten Usern

                      Die Struktur hattest Du schon beschrieben. Was stehen für Daten in den Tabellen (nur ein paar Beispieldaten, damit man Deine Abfragen mal nachvollziehen kann)?

                      MfG,
                      EKKi

                      --
                      sh:( fo:| ch:? rl:( br:> n4:~ ie:% mo:} va:) de:] zu:) fl:{ ss:) ls:& js:|
                      1. Dann nutze das für die Entwicklung Deiner Abfragen - einfach solange daran herumbasteln, bis sie genau das zurückliefern, was Du haben willst. Erst dann lohnt sich der Einbau der Abfragen in Deinen PHP-Code.

                        ok, das macht sinn

                        Die Struktur hattest Du schon beschrieben. Was stehen für Daten in den Tabellen (nur ein paar Beispieldaten, damit man Deine Abfragen mal nachvollziehen kann)?

                        tabelle projekt:

                        id      Projekt
                        37      Die Sendung mit dem Dingens
                        38  Sendung Bla
                        31  projekt1
                        32  projekt2
                        33  projekt3
                        35  projekt4
                        36  projektXXX

                        tabelle users:

                        UserID  UserName  UserStatus  UserSession
                        2  Karsten         Admin    cecgn7lhis4pfartsrojj3eei6
                        3  Panchos  Producer  NULL
                        4  Tobi          Projektleiter  NULL
                        5  Azadeh          Producer  NULL
                        6  Lukas          Admin          NULL
                        7  Martin          Producer  NULL

                        tabelle dispo_tec:
                        id  pr_id  user_id
                        10  37  2
                        12  37  7
                        13  37  3
                        14  38  3
                        15  38  4

          2. Mahlzeit Paco,

            Für das Sortieren ist das DBMS zuständig. Die Programmiersprache sollte dann (eigentlich) nur noch Zeile für Zeile untereinander schreiben.
            Ja, das seh ich ja auch so. Aber das Prinzip wie ich in der ersten schleife die Projekte abarbeite und dann für jedes Projekt die User mittels einer weiteren Schleife will mir nicht in den Schädel.

            Wieso in einer weiteren Schleife? Welches Datenbanksystem verwendest Du (das hast Du immer noch nicht gesagt!)? Eigentlich gibt es in jedem mir bekannten Funktionen zum Gruppieren von Ergebnissen ...

            $query = "SELECT projekt, UserName
                        FROM
                            projekte
                        LEFT JOIN
                            dispo_tec
                        ON
                            projekte.projekt = dispo_tec.pr_id
                        LEFT JOIN
                            users
                        ON
                            dispo_tec.user_id = users.UserID
                        ";

            Ein kleiner Tipp für Dich für die Zukunft: die Benennung Deiner Tabellen und Spalten ist grauenhaft! Verwende eine einheitliche - ansonsten hast Du irgendwann später, wenn Du Deine Tabellen bzw. Skripte nach einer gewissen Zeit wieder anfasst absolut keine Orientierung mehr.

            Entweder deutsche Namen oder englische - aber keinen Mischmasch! Entweder Mixed-Case-Schreibung oder Trennung der Wortteile durch Unterstriche - aber keinen Mischmasch! Foreign-Key-Felder würde ich einheitlich genau so benennen, wie die Tabelle heißt, auf die sie referenzieren!

            $sql = mysql_query($query) or die(mysql_error());

            Siehe dazu Zitat 1282. Was passiert, wenn die Abfrage zwar fehlerfrei klappt, aber die Ergebnismenge leer ist? Du solltest die Rückgabewerte der von Dir aufgerufenen Funktionen auch auswerten. Darüber hinaus ist der Variablenname "$sql" äußerst ungeeignet - oder enthält die Variable etwa SQL? Nein, sie enthält ein Ergebnis einer Datenbankabfrage.

            MfG,
            EKKi

            --
            sh:( fo:| ch:? rl:( br:> n4:~ ie:% mo:} va:) de:] zu:) fl:{ ss:) ls:& js:|
  2. Hi,

    ergänzend zu EKKis Antwort:

    $query = "SELECT * FROM projekte ORDER BY projekt";

    Niemals, *niemals* selektiere pauschal "*". Gib *immer* diejenigen Spalten an, die Du benötigst.

    Cheatah

    --
    X-Self-Code: sh:( fo:} ch:~ rl:° br:> n4:& ie:% mo:) va:) de:] zu:) fl:{ ss:) ls:~ js:|
    X-Self-Code-Url: http://emmanuel.dammerer.at/selfcode.html
    X-Will-Answer-Email: No
    X-Please-Search-Archive-First: Absolutely Yes