jakkob: Anfängerfrage zu Datenbanken / JOIN

Hallo, eigentlich *müsste* es hierzu eine einfache Lösung geben. Ich war allerdings in den letzten 1,5h zu dämlich, sie zu finden...

Ich will einfach nur eine 1:n Beziehung darstellen und auslesen:

Ich habe dafür zwei Tabellen, die jeweils 1:1 Bez. beinhalten. Die erste besteht aus 1:1 Beziehungen, also meinetwegen

haupt_id, vorname, nachname

Die zweite enthält Adressen (und halt evtl. mehrere) in der Form
email_id, haupt_id, email

Das ganze deswegen, da ja ein User mehere email-Adressen haben kann.

Wenn ich jetzt eine join-Anfrage mache

SELECT
h.vorname, h.nachname e.email
FROM
user u
JOIN
email e
ON h.hauptid = e.emailid'

und eine Name drei Emailadressen hat, drei Array raus, in denen jeweils Vorname, Nachname und eine der drei Adtressen stehen. Ich möchte aber natürlich gerne ein Aray haben, in dem genau einmal der Name steht und trotzdem alle Adressen...
wie mache ich das...

...und sorry...die Frage kommt mir sehr leicht vor, aber ich kann euch versichern, dass ich schon exzessiv gegoogelt habe umd diesem Problem auf die Schliche zu kommen...

thx
J

  1. yo,

    und eine Name drei Emailadressen hat, drei Array raus, in denen jeweils Vorname, Nachname und eine der drei Adtressen stehen. Ich möchte aber natürlich gerne ein Aray haben, in dem genau einmal der Name steht und trotzdem alle Adressen...
    wie mache ich das...

    erst einmal sich bewußt machen, dass du kein array hast, sondern es um rdbms geht, sprich du bekommst eine ergebnismenge mit einer bestimmten anzahl von datenseätzen. oder mit anderen worten, es ist vollkommen normal, dass du bei einer 1:n beziehung mehrere datensätze zurück bekommst.

    willst du sie anders darstellen, so komtm das entweder auf die eigenheiten deines dbms drauf an oder aber du musst die darstellung auf eine andere ebene vornehmen, stadard sql sieht meines wissen keine funktionalität für einen gruppenwechsel vor.. benutzt du zum beispiel mysql, dann würde sich GROUP_CONCAT anbieten. oracle, bzw. sqlplus bietet auch funktionalitäten bezüglich des gruppenwechsels in einer ergebnismenge an. also wäre das beste von dir zu erfahren, welches dbms und welche version du benutzt.

    Ilja

    1. erst einmal sich bewußt machen, dass du kein array hast, sondern es um rdbms geht, sprich du bekommst eine ergebnismenge mit einer bestimmten anzahl von datenseätzen.

      Okay, das ist mir schon bewusst. Aber oft wird man da ja jetzt ein Array draus machen.

      oder mit anderen worten, es ist vollkommen normal, dass du bei einer 1:n beziehung mehrere datensätze zurück bekommst.

      Gut, wenn das normal ist, dann frage ich, ob es besser geht? :-) Sprich, ob MYSQL 5.0.51b (XAMPP, zum testen halt...)  mir auch eine Ergebnismenge zurückliefern kann, in der genau einmal der vorname, einmal der nachname und alle adressen stehen.

      Na klar, ich könnte mir mein gewolltes Array auch aus der Ergebnismenge bauen, in der dreimal der gleiche Name mit jeweils einer neuen Adresse steht...dachte nur das ginge auch geschickter?? :-(

      GROUP_CONCAT

      hilft mir hierbei nicht unbedingt weiter. Das verkettet die Ergebnisse ja nur zu einem string. Kann ich aber bei einer anderen Sache gut gebrauchen, danke

      Also keine besser Lösung für diese Abfrage? Das müsste doch ein allerweltsproblem sein...
      thx
      J

      1. Hello,

        Also keine besser Lösung für diese Abfrage? Das müsste doch ein allerweltsproblem sein...

        jein, eine Faustregel des Datenbankdesigns lautet "Daten vor Funktion", d.h. man modelliert ein sauberes Datenmodell, daraus leitet man die notwendigen Transformationen ab um die Funktionen der umliegenden Anwendung abzubilden. Ist natürlich etwas zu hart gesagt, aber es empfiehlt sich nicht eine Speicherstruktur nur deshalb zu wählen, weil sie leicht zu lesen ist - das beste Beispiel dafür sind so riesige Excel-"Datenbanken", in der einfach alle Daten als ein einzelnes Arbeitsblatt abgelegt sind.
        Ja, du hast dort ein nicht ganz handliches Ergebnis in den Fingern, aber das ist normal. Ilja hat dir mit Gruppenwechsel schon das richtige Stichwort gegeben.

        MfG
        Rouven

        --
        -------------------
        sh:| fo:} ch:? rl:( br:& n4:{ ie:| mo:} va:) js:| de:] zu:| fl:( ss:) ls:& (SelfCode)
        "I wish it need not have happened in my time" - "So do I, and so do all who live to see such times. But that is not for them to decide. All we have to decide is what to do with the time that is given us."  --  J.R.R. Tolkien: "The Lord Of The Rings: The Fellowship Of The Ring"
        1. @Ilja
          hehe, nimms mir nicht überl, wenn ich Dich mit Dir selber beantworte:

          PHP hat sicherlich gute methoden, diese string wieder aufzulösen. wundert mich, dass du damit nichts anfangen kannst.

          und es macht auch sinn, die dinge dort anzugehen, wo sie entstehen und das ist in deinem falle mysql.

          ..

          ich hatte vorhin schon einen rel. langen Text geschrieben, aber dann habe ich noch ein bisschen rumprobiert und dann dachte ich:
          Sch.... auf die JOIN Abfrage! und mache jetzt halt eine einfache Abfrage mehr...Dann bin ich diese ganzen Probleme mit irgendwelchen doppelten Ergebnissen los. Ich mache es jetzt so, dass ich über JOIN nur die IDs der Datensätze abfrage, die meine suche "matchen" und dann frage ich mit dieser ID und DISTINCT nochmal alles andre ab, was ich brauche.

          vielen Dank für eure Hilfe, ich komm bestimmt wieder :-)

          greetz
          J

          1. yo,

            Sch.... auf die JOIN Abfrage! und mache jetzt halt eine einfache Abfrage mehr...Dann bin ich diese ganzen Probleme mit irgendwelchen doppelten Ergebnissen los. Ich mache es jetzt so, dass ich über JOIN nur die IDs der Datensätze abfrage, die meine suche "matchen" und dann frage ich mit dieser ID und DISTINCT nochmal alles andre ab, was ich brauche.

            klingt nicht gut, aber dazu müssten wir genau wissen, was du vorhast....

            Ilja

            1. klingt nicht gut

              Warum genau klingt das nicht gut? Wegen meiner ungehobelten Ausdrucksweise oder wegen des beschriebenen Vorgehens?

              »»aber dazu müssten wir genau wissen, was du vorhast...
              um beim Besipiel von oben zu bleiben (also email ist die einzige Infornmation, bei der mehrere Angabee möglich sind -->1:n Bez.) suche ich so nach einer vornamen <-> email Übereinstimmung:

                
              SELECT DISTINCT 	u.userid, u.vorname, u.nachname  
              FROM                    user u  
              JOIN 			email e  
              USING 		 	(userid)  
              WHERE                   u.vorname='myVorname'  
              AND                     e.email = 'myEmail'  
              
              

              Und wenn ich jetzt diese userid habe, dann geh ich halt nochmal in die email-Tabelle rein und hole mir dort alle Emails für diese id raus. Jetzt kann ich vorname, nachname und alle emails angeben...So funktioniert, und ich bin zufreiden :-)

              Wenn ichs aber in einer Abfrage versuche, also in SELECT noch e.mail schreibe, dann kommt für eine Suche nach Vorname+Nachname (also ohne nach myEmail zu suchen) für jede Email-Adresse ein Ergebnis raus.

              Wenn ich allerdings nach genau 'myEmail' suche, dann kommt aber immer nur genau ein Ergebnis, aber ich will ja alle Emails haben.

              Mit einer Abfrage gehts also nicht. Liegt aber wohl nicht nur an der 1:n Bez. sondern zusätzlich daran, dass ich nicht weiss, ob meine Suchanfrage auch nach emails (also der 1:n Bez.) suchen soll, oder nicht, denn das entscheidet der User.

              Aber nun gut, mit zwei Abfragen siehts doch eigentlich ganz vernünftig aus, oder?

              vielen Dank
              J

      2. yo,

        Okay, das ist mir schon bewusst. Aber oft wird man da ja jetzt ein Array draus machen.

        nicht so oft, wei du es dir vorstellst. ich arbeite zum beispiel sehr viel mit sql, und nur sql. da ist von arrays weit und breit nichts zu sehen. und es macht auch sinn, die dinge dort anzugehen, wo sie entstehen und das ist in deinem falle mysql.

        Gut, wenn das normal ist, dann frage ich, ob es besser geht? :-) Sprich, ob MYSQL 5.0.51b (XAMPP, zum testen halt...)  mir auch eine Ergebnismenge zurückliefern kann, in der genau einmal der vorname, einmal der nachname und alle adressen stehen.

        nun besser ist ja realtiv. aber es gibt einen kleinen work around. vorrausseetzung dafür ist, dass du die maxinmale anzahl der adressen kennst und auch nur händelbar, wenn sie nicht zu gross ist. dann könnten korrelierte unterabfragen zum einsatz kommen.

        »»  GROUP_CONCAT

        hilft mir hierbei nicht unbedingt weiter. Das verkettet die Ergebnisse ja nur zu einem string. Kann ich aber bei einer anderen Sache gut gebrauchen, danke

        nun, die adressen liegen ja so oder so in einem string vor und PHP hat sicherlich gute methoden, diese string wieder aufzulösen. wundert mich, dass du damit nichts anfangen kannst.

        Ilja

  2. Wenn ich jetzt eine join-Anfrage mache

    SELECT
    h.vorname, h.nachname e.email
    FROM
    user u
    JOIN
    email e
    ON h.hauptid = e.emailid'

    Bei dieser Abfrage bekommst Du eine Ergebnismenge?

    Bitte korrigiert mich, wenn ich falsch liege, aber das kann ich mir nicht vorstellen ;-)

    Grüße, Franz