Maik W. aus E.: Join über mehrere Tabellen

Tach zusammen,

ich habe hier eine mySQL-DB (4.1.15 auf dem Testserver, 5.0.32 produktiv), in der ich drei Tabellen habe:

arztdaten
    arzt_id| Daten | Daten | Daten...
history
    history_id | ... | history_text
arzt_hi (verknüpft n:m arztdaten und history)
    arzt_ref| history_ref

Jetzt möchte ich eine Liste aller arzt_ids und ein paar Daten, bei denen in der zugehörigen History ein bestimmter History-Text steht und ein bestimmter andere eben nicht.

was ich habe:

  
SELECT ahi1.arzt_ref, ahi1.history_ref, h1.historytext, ahi2.arzt_ref, ahi2.history_ref, h2.historytext  
FROM arzt_hi AS ahi1, history AS h1, history AS h2  
INNER JOIN arzt_hi AS ahi2 ON ahi1.arzt_ref = ahi2.arzt_ref  
WHERE ahi1.history_ref = h1.historyid  
AND h1.historytext LIKE 'Initialanschreiben erhalten'  
AND ahi2.history_ref = h2.historyid  
AND h2.historytext NOT LIKE 'Rückmeldung'  
GROUP BY ahi1.arzt_ref  
ORDER BY ahi1.arzt_ref  

Aber irgendwie kommt da noch zu viel raus, nämlich alles. Kann wer helfen?

Danke

Maik

--
Margin-Regler am Control-Data-Tischrechner im RRZE Erlangen
Mehr margin! Sag ich ja immer...
  1. Hallo Maik,

    ich weiß nur, dass Vinzenz immer wieder frustriert ist, wenn man trotz Lektüre seines dataillierten Howtos das nicht hinbekommt (;-). Das hast Du sicher gelesen hier bei selfhtml, oder?

    Kleiner blöder Tipp am Rande: reduzier doch Dein Problem mal nur auf den Join und fange vielleicht mit zwei Tabellen an, ohne AS und SORT und soweiter.

    Gruß

    jobo

    1. Tach auch jobo,

      ich weiß nur, dass Vinzenz immer wieder frustriert ist, wenn man trotz Lektüre seines dataillierten Howtos das nicht hinbekommt (;-). Das hast Du sicher gelesen hier bei selfhtml, oder?

      Ja sicher, sonst wäre ich ja gar nicht erst so weit gekommen...

      Kleiner blöder Tipp am Rande: reduzier doch Dein Problem mal nur auf den Join und fange vielleicht mit zwei Tabellen an, ohne AS und SORT und soweiter.

      Ähh, ohne AS und so würde der Join nicht im Ansatz funktionieren, weil ich ja zweimal auf die gleiche Tabelle zupacken muß...

      Maik

      --
      Margin-Regler am Control-Data-Tischrechner im RRZE Erlangen
      Mehr margin! Sag ich ja immer...
      1. Hallo,

        Ähh, ohne AS und so würde der Join nicht im Ansatz funktionieren, weil ich ja zweimal auf die gleiche Tabelle zupacken muß...

        Naja, ich hatte schon befürchtet, dass Du da schon Meilen voraus bist meinem Kenntnisstand (;-). Also auf Vinzenz warten.

        Gruß

        jobo

  2. Mahlzeit Maik W. aus E.,

    was ich habe:

    SELECT ahi1.arzt_ref, ahi1.history_ref, h1.historytext, ahi2.arzt_ref, ahi2.history_ref, h2.historytext
    FROM arzt_hi AS ahi1, history AS h1, history AS h2
    INNER JOIN arzt_hi AS ahi2 ON ahi1.arzt_ref = ahi2.arzt_ref
    WHERE ahi1.history_ref = h1.historyid
    AND h1.historytext LIKE 'Initialanschreiben erhalten'
    AND ahi2.history_ref = h2.historyid
    AND h2.historytext NOT LIKE 'Rückmeldung'
    GROUP BY ahi1.arzt_ref
    ORDER BY ahi1.arzt_ref

      
    Du solltest zuerst diese Abfrage bereinigen - eine Mischform von expliziten und impliziten JOINs ist eigentlich nie wirklich sinnvoll, übersichtlich und verständlich. Vorschlag:  
      
    ~~~sql
    SELECT ahi1.arzt_ref  
    ,      ahi1.history_ref  
    ,      h1.historytext  
    ,      ahi2.arzt_ref  
    ,      ahi2.history_ref  
    ,      h2.historytext  
      FROM arzt_hi       AS ahi1  
      INNER JOIN arzt_hi AS ahi2 ON ahi1.arzt_ref = ahi2.arzt_ref  
      JOIN history       AS h1   ON ahi1.history_ref = h1.historyid  
      JOIN history       AS h2   ON ahi2.history_ref = h2.historyid  
     WHERE h1.historytext LIKE 'Initialanschreiben erhalten'  
       AND h2.historytext NOT LIKE 'Rückmeldung'  
     GROUP BY ahi1.arzt_ref  
     ORDER BY ahi1.arzt_ref
    

    Zuerst einmal ist diese Abfrage unsauber, da Du lediglich über eine Spalte gruppierst, Dir aber weitere zusätzliche Spalten ohne passende Aggrgatsfunktion ausgeben lässt. Jedes andere DBMS außer MySQL würde Dir die Abfrage wieder um die Ohren hauen - und selbst MySQL muss raten, was Du haben willst ... es gibt keine Garantie dafür, dass das immer die gleichen Daten sind. Behebe also diesen Fehler.

    Warum hast Du jetzt eine zweite Verknüpfungstabelle (ahi2) zur ersten (ahi1) dazugejoint? Warum joinst Du jeweils eine History-Tabelle zu jeder der beiden Verknüpfungstabellen?

    Deine Anforderung war:

    Jetzt möchte ich eine Liste aller arzt_ids und ein paar Daten, bei denen in der zugehörigen History ein bestimmter History-Text steht und ein bestimmter andere eben nicht.

    Du sprichst von *DER* zugehörigen History - benutzt aber zwei. Irgendwie ist mir das Datenmodell und das, was Du willst, noch nicht so ganz klar.

    Aber irgendwie kommt da noch zu viel raus, nämlich alles. Kann wer helfen?

    Definiere Deine Anforderungen genauer.

    MfG,
    EKKi

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

      Danke für Deine Rückmeldung.

      SELECT ahi1.arzt_ref

      ,      ahi1.history_ref
      ,      h1.historytext
      ,      ahi2.arzt_ref
      ,      ahi2.history_ref
      ,      h2.historytext
        FROM arzt_hi       AS ahi1
        INNER JOIN arzt_hi AS ahi2 ON ahi1.arzt_ref = ahi2.arzt_ref
        JOIN history       AS h1   ON ahi1.history_ref = h1.historyid
        JOIN history       AS h2   ON ahi2.history_ref = h2.historyid
      WHERE h1.historytext LIKE 'Initialanschreiben erhalten'
         AND h2.historytext NOT LIKE 'Rückmeldung'
      GROUP BY ahi1.arzt_ref
      ORDER BY ahi1.arzt_ref

        
      
      > Zuerst einmal ist diese Abfrage unsauber, da Du lediglich über eine Spalte gruppierst, Dir aber weitere zusätzliche Spalten ohne passende Aggrgatsfunktion ausgeben lässt. Jedes andere DBMS außer MySQL würde Dir die Abfrage wieder um die Ohren hauen -  
      
      ich weiß, ich weiß... habe das gemacht, um zu sehen, ob ich ansatzweise in die richtige Richtung tüftle.  
        
      
      > Warum hast Du jetzt eine zweite Verknüpfungstabelle (ahi2) zur ersten (ahi1) dazugejoint? Warum joinst Du jeweils eine History-Tabelle zu jeder der beiden Verknüpfungstabellen?  
      >   
      > Deine Anforderung war:  
      >   
      > > Jetzt möchte ich eine Liste aller arzt\_ids und ein paar Daten, bei denen in der zugehörigen History ein bestimmter History-Text steht und ein bestimmter andere eben nicht.  
      >   
      > Du sprichst von \*DER\* zugehörigen History - benutzt aber zwei.  
      
      Ich dachte, daß ich ja zwei Abfragen brauche, einmal ob ein Wert "Initialanschreiben" da ist  und einmal ob ein Wert "Rückmeldung" nicht da ist.  
        
      
      > Irgendwie ist mir das Datenmodell und das, was Du willst, noch nicht so ganz klar.  
        
      Kein Problem, also:  
        
      history:  
        
      id | history\_text  
      1  | Initialanschreiben erhalten  
      2  | Initialanschreiben erhalten  
      3  | Rückmeldung  
        
      arzt\_hi:  
        
      arzt\_ref | history\_ref  
        1        |      1  
        2        |      2  
        1        |      3  
        
      In der History-Tabelle werden alle Einträge für alle Ärzte gespeichert, die Verknüpfung auf die Arzt-Id wird über die arzt\_hi gelöst. Jetzt möchte ich die IDs der Ärzte, die einen "Initialanschreiben"-Eintrag haben, aber nicht "Rückmeldung", hier als Beispiel die ID '2'  
        
      
      > Definiere Deine Anforderungen genauer.  
        
      Besser?  
        
      Gruß  
        
      Maik
      
      -- 
      ![Margin-Regler am Control-Data-Tischrechner im RRZE Erlangen](http://www.gruss-aus-essen.de/selfforum/mehr_margin.jpg)  
      Mehr margin! Sag ich ja immer...  
      
      
  3. moin,

    ich habe hier eine mySQL-DB (4.1.15 auf dem Testserver, 5.0.32 produktiv), in der ich drei Tabellen habe:

    wenn möglich versuche beides auf die gleiche version zu bringen. kann zu überraschungen im unterschiedlichen verhalten führen.

    Jetzt möchte ich eine Liste aller arzt_ids und ein paar Daten, bei denen in der zugehörigen History ein bestimmter History-Text steht und ein bestimmter andere eben nicht.

    mal von deiner impliziter JOIN schreibweise abgesehen, auf die du schon hingewiesen wurdest, sind JOINS in vielen fällen "böse". das kommt aber immer auf die jeweilige verwendung drauf an. wenn du nur daten aus der tabelle arztdaten in der projektion ausgeben willst, dann solltest du JOINS vermeiden und korrelierte unterabfragen zum einsatz kommen lassen, die in die WHERE klausel eingebaut werden, um die gewünschten datensätze zu selektieren.

    SELECT a.arzt_id, a.spalte2, a.spalte2....
    FROM arztdaten a
    WHERE EXISTS (SELECT NULL
                  FROM arzt_hi ah
                  INNER JOIN history h ON h.history_id  = ah.history_ref
                  WHERE ah.arzt_ref = a.arzt_id
                  AND h.historytext = 'Initialanschreiben erhalten'
                 )
    AND NOT EXISTS (SELECT NULL
                    FROM arzt_hi ah
                    INNER JOIN history h ON h.history_id  = ah.history_ref
                    WHERE ah.arzt_ref = a.arzt_id
                    AND h.historytext = 'Rückmeldung'
                   )
    ;

    Ilja

    1. Tach auch Ilja,

      wenn du nur daten aus der tabelle arztdaten in der projektion ausgeben willst, dann solltest du JOINS vermeiden und korrelierte unterabfragen zum einsatz kommen lassen, die in die WHERE klausel eingebaut werden, um die gewünschten datensätze zu selektieren.

      Sehr elegante Lösung! Très chic!

      SELECT a.arzt_id, a.spalte2, a.spalte2....
      FROM arztdaten a
      WHERE EXISTS (SELECT NULL
                    FROM arzt_hi ah
                    INNER JOIN history h ON h.history_id  = ah.history_ref
                    WHERE ah.arzt_ref = a.arzt_id
                    AND h.historytext = 'Initialanschreiben erhalten'
                   )
      AND NOT EXISTS (SELECT NULL
                      FROM arzt_hi ah
                      INNER JOIN history h ON h.history_id  = ah.history_ref
                      WHERE ah.arzt_ref = a.arzt_id
                      AND h.historytext = 'Rückmeldung'
                     )
      ;

      Jo, das klappt, wieder was gelernt, Besten Dank!

      Maik

      --
      Margin-Regler am Control-Data-Tischrechner im RRZE Erlangen
      Mehr margin! Sag ich ja immer...
    2. Hallo Ilja.

      SELECT a.arzt_id, a.spalte2, a.spalte2....
      FROM arztdaten a
      WHERE EXISTS (SELECT NULL
                    FROM arzt_hi ah
                    INNER JOIN history h ON h.history_id  = ah.history_ref
                    WHERE ah.arzt_ref = a.arzt_id
                    AND h.historytext = 'Initialanschreiben erhalten'
                   )
      AND NOT EXISTS (SELECT NULL
                      FROM arzt_hi ah
                      INNER JOIN history h ON h.history_id  = ah.history_ref
                      WHERE ah.arzt_ref = a.arzt_id
                      AND h.historytext = 'Rückmeldung'
                     )
      ;

      Hast du eine Buchempfehlung oder ein paar gute Internetseiten wo man sich sollche SQL-Techniken beibringen kann, abgesehen von der umfangreichen offiziellen Doku?

      Lieben Gruß,

      John

      1. moin,

        Hast du eine Buchempfehlung oder ein paar gute Internetseiten wo man sich sollche SQL-Techniken beibringen kann, abgesehen von der umfangreichen offiziellen Doku?

        hmm, in den meisten büchern ist sql ist immer nur ein teil vom gesamtthema datenbanken und dann oftmals auch nur die basics, was sql betrifft. inner aller regel geht das nicht über joins hinaus. ich kenne eigentlich so aus dem stehgreif kein buch, was sich ein wenig intensiver mit sql abfragen beschäftigt. meines ertes buch war "SQL, der schlüssel zu relationalen datenbanken", aber auch dort gilt oben genanntes.

        vielleicht das buch "advanced SQL" von daniel warner, das gab (gibt ?) es für lau bei terrrashop oder amazon.de, dort sind wengitens korrelierte unterabfragen mal aufgeführt. aber auch dort geht es nicht nur um sql und nicht mit allem was dort steht, mit dem bin ich zufrieden.

        ich wollte hier auch mal einen beitrag zum thema datenbanken bei selfhtml schreiben, aber dazu kam es nicht.

        Ilja

        1. Tach auch Ilja,

          ich wollte hier auch mal einen beitrag zum thema datenbanken bei selfhtml schreiben, aber dazu kam es nicht.

          Woran lag's? Könnte es in Zukunft dazu kommen? Also ich fände es klasse, wenn Dein Wissen hier strukturiert erläutert würde, und man nicht die Erkenntnis nehmen und in Nachhinein zusammenstöppeln müßte. Ich gebe Dir gerne das Template für einen Artikel...

          Grüße

          Maik

          --
          Margin-Regler am Control-Data-Tischrechner im RRZE Erlangen
          Mehr margin! Sag ich ja immer...
          1. moin,

            »» ich wollte hier auch mal einen beitrag zum thema datenbanken bei selfhtml schreiben, aber dazu kam es nicht.

            Woran lag's?

            ganz genau kann ich das auch nicht sagen, allerdings haben hier schon kompetende menschen einen artikel über datenbanken geschrieben.

            Ilja

            1. Hallo,

              ganz genau kann ich das auch nicht sagen, allerdings haben hier schon kompetende menschen einen artikel über datenbanken geschrieben.

              Ich dachte, Vinzenz hätte. (http://forum.de.selfhtml.org/archiv/2008/8/t176055/#m1158145), da war Ilja ja mit dabei (;-). )

              Gruß

              jobo

              1. moin,

                Ich dachte, Vinzenz hätte. (http://forum.de.selfhtml.org/archiv/2008/8/t176055/#m1158145), da war Ilja ja mit dabei (;-). )

                es geht weniger um beiträge im forum, sondern eher um artikel wie diese hier:

                http://aktuell.de.selfhtml.org/artikel/datenbanken/

                Ilja

                1. Hallo,

                  moin,

                  »» Ich dachte, Vinzenz hätte. (http://forum.de.selfhtml.org/archiv/2008/8/t176055/#m1158145), da war Ilja ja mit dabei (;-). )

                  es geht weniger um beiträge im forum, sondern eher um artikel wie diese hier:

                  http://aktuell.de.selfhtml.org/artikel/datenbanken/

                  Natürlich, darauf bezieht sich Vinzenz ja in o.g. Link:

                  "wenn es irgendwo vom Verständnis hakt, wäre ich Dir für eine Rückmeldung dankbar. Mein Artikel ist zwar seit über zwei Jahren unverändert, aber das heißt nicht, dass er nicht verbessert werden kann. Für den Autor ist es oft sehr schwer nachzuvollziehen, wo der Leser hängenbleibt, wo ein zu großer Sprung ist, wo etwas nicht exakt genug erklärt ist, ..."

                  Gruß

                  jobo

                  1. moin,

                    Natürlich, darauf bezieht sich Vinzenz ja in o.g. Link:

                    und wie kommmst du dann darauf, dass ich mit dabei war ? meine mitarbeit an den beiträgen war meiner meinung nach nicht erwünscht, aber die genauen hintergründe kenne ich nicht.

                    Ilja

                    1. Hallo,

                      und wie kommmst du dann darauf, dass ich mit dabei war ? meine mitarbeit an den beiträgen war meiner meinung nach nicht erwünscht, aber die genauen hintergründe kenne ich nicht.

                      Bei dem Thread war doch auch ein Ilja, nicht bei der Doku.
                      Gruß

                      jobo

                      1. moin,

                        Bei dem Thread war doch auch ein Ilja, nicht bei der Doku.

                        hier sind sicherlich einige threads mit meiner beteiligung. aber ich hatte dir schon probiert klar zu machen, dass es nicht um die beiträge hier im forum geht, sondern um ganz autarke artikel, was du als Doku bezeichnest. damals hatte ich vorgeschlagen, einen solchen zu schreiben, aber man wollte das wohl nicht.

                        Ilja

                        1. Hallo,

                          moin,

                          »»  Bei dem Thread war doch auch ein Ilja, nicht bei der Doku.

                          hier sind sicherlich einige threads mit meiner beteiligung. aber ich hatte dir schon probiert klar zu machen, dass es nicht um die beiträge hier im forum geht, sondern um ganz autarke artikel, was du als Doku bezeichnest. damals hatte ich vorgeschlagen, einen solchen zu schreiben, aber man wollte das wohl nicht.

                          doch, habe ich schon kapiert. vinzenz bat ja darum, seinen artikel zu überarbeiten, um das verständnis zu erhöhen.

                          Gruß

                          jobo

                          1. moin,

                            doch, habe ich schon kapiert. vinzenz bat ja darum, seinen artikel zu überarbeiten, um das verständnis zu erhöhen.

                            du kennst vielleicht dir hintergründe nicht, aber ich wiederhole es gerne noch mal. ich denke nicht, dass meine mitarbeit an den artikeln erwünscht ist.

                            Ilja

                            1. Hallo,

                              moin,

                              »» doch, habe ich schon kapiert. vinzenz bat ja darum, seinen artikel zu überarbeiten, um das verständnis zu erhöhen.

                              du kennst vielleicht dir hintergründe nicht, aber ich wiederhole es gerne noch mal. ich denke nicht, dass meine mitarbeit an den artikeln erwünscht ist.

                              Ja, hatte ich schon verstanden.

                              Gruß

                              jobo