Rainer: Welcher Join

Hallo,

es geht um eine MSSQL-Datenbank.

Das Prinzip ist, dass in Tabelle A ein Datensatz abgefragt wird, und in Tabelle B geschaut wird, ob dort zu der ID in Tabelle A Einträge vorhanden sind.
Als Beispiel: Tabelle A beinhaltet Mannschaften, Tabelle B beinhaltet alle Spieler aller Mannschaften und besitzt ein Feld "mannschaft_id" um den Spieler zu einer Mannschaft zuzuordnen.

Das Problem ist, dass wenn es nur eine Mannschaft aber keine zugehörigen Spieler gibt, der Query nichts zurückgibt.

Ich darf euch leider nichts von dem Original-Code geben, das ist Betriebsgeheimnis. Ich kann euch aber sagen, dass diese Abfrage momentan mit einem INNER-Join läuft der so aussieht:

FROM Mannschaft
    INNER JOIN Spieler ON Mannschaft.ID = Spieler.Mannschaft_ID

Soweit ich das mit den Joins begriffen habe, muss ich den INNER-Join zu einem anderen umwandeln, richtig? Und welchen?

MfG
Rainer

  1. Hi,

    versuch es mal mit einem left join anstatt inner join. Falls das nicht das gewünschte ergebnis bringt mit einem right join.

    gruß
    Andrera

    1. Hi

      versuch es mal mit einem left join anstatt inner join. Falls das nicht das gewünschte ergebnis bringt mit einem right join.

      Nach meinem Post habe ich das schon probiert, aber alle Varianten brachten keinen Datensatz.
      Ich glaube, es liegt daran, dass dieser eine Join nur der erste in einer Reihe von vielen ist. Es kommen zuerst 2 Inner-Joins (darunter auch der, den ich euch gegeben habe), darauf folgen 7 Left-Joins. Ist das von Bedeutung?

      MfG
      Rainer

      1. Hello,

        Ich glaube, es liegt daran, dass dieser eine Join nur der erste in einer Reihe von vielen ist. Es kommen zuerst 2 Inner-Joins (darunter auch der, den ich euch gegeben habe), darauf folgen 7 Left-Joins. Ist das von Bedeutung?

        jein - es gilt die Regel "einmal kein Ergebnis, immer kein Ergebnis". Die LEFT JOINs verlieren keine Ergebnisse sofern du ihnen mal welche beim Start gegeben hast, die INNER JOINs schon. Wenn dein zweiter INNER JOIN in Ermangelung von Ergebnissen fehlschlägt, dann bekommst du auch insgesamt kein Ergebnis, es würde daher, sofern das fachlich in Ordnung ist, Sinn machen auch den zweiten INNER durch einen LEFT JOIN zu ersetzen.

        MfG
        Rouven

        --
        -------------------
        sh:| fo:} ch:? rl:( br:& n4:{ ie:| mo:} va:) js:| de:] zu:| fl:( ss:) ls:& (SelfCode)
        Let Bygones Be Bygones  --  Robert Pitscottie: "Chronicles of Scotland"
        1. Hi

          jein - es gilt die Regel "einmal kein Ergebnis, immer kein Ergebnis". Die LEFT JOINs verlieren keine Ergebnisse sofern du ihnen mal welche beim Start gegeben hast, die INNER JOINs schon. Wenn dein zweiter INNER JOIN in Ermangelung von Ergebnissen fehlschlägt, dann bekommst du auch insgesamt kein Ergebnis, es würde daher, sofern das fachlich in Ordnung ist, Sinn machen auch den zweiten INNER durch einen LEFT JOIN zu ersetzen.

          Ahja, jetzt habe ich nur noch Left-Joins, aber geändert hat sich wieder nichts. Das heißt, dass die Joins nicht Schuld sind, sondern das Where?
          Inwieweit könnt ihr mir überhaupt helfen, ohne dass ihr den ganzen SQL seht?

          MfG
          Rainer

          1. Hello,

            Ahja, jetzt habe ich nur noch Left-Joins, aber geändert hat sich wieder nichts. Das heißt, dass die Joins nicht Schuld sind, sondern das Where?
            Inwieweit könnt ihr mir überhaupt helfen, ohne dass ihr den ganzen SQL seht?

            jetzt gar nicht mehr :-)

            Die Joins sind ein berechtigter Ansatzpunkt, da sie dein Statement mit Sicherheit ins Leere laufen lassen, sobald irgendwo ein Datensatz fehlt. Wenn nach Ersetzen der Joins immer noch nichts kommt ist entweder deren Reihenfolge falsch (--> a LEFT JOIN b benötigt in a Datensätze, in b nicht unbedingt), oder  die WHERE Klausel eliminiert die tatsächlichen Ergebnisse - filtert vielleicht jemand auf eine gültige Spielernummer oder so?
            Aber ab jetzt geht das Stochern im Nebel los...

            MfG
            Rouven

            --
            -------------------
            sh:| fo:} ch:? rl:( br:& n4:{ ie:| mo:} va:) js:| de:] zu:| fl:( ss:) ls:& (SelfCode)
            Eine Bilanz ist wie der Bikini einer Frau. Sie zeigt fast alles, aber verdeckt das Wesentliche  --  Günter Stotz, Regierungsdirektor des baden-württembergischen Wirtschaftsministeriums
            1. Hi

              Inwieweit könnt ihr mir überhaupt helfen, ohne dass ihr den ganzen SQL seht?
              jetzt gar nicht mehr :-)

              Die Joins sind ein berechtigter Ansatzpunkt, da sie dein Statement mit Sicherheit ins Leere laufen lassen, sobald irgendwo ein Datensatz fehlt. Wenn nach Ersetzen der Joins immer noch nichts kommt ist entweder deren Reihenfolge falsch (--> a LEFT JOIN b benötigt in a Datensätze, in b nicht unbedingt), oder  die WHERE Klausel eliminiert die tatsächlichen Ergebnisse - filtert vielleicht jemand auf eine gültige Spielernummer oder so?
              Aber ab jetzt geht das Stochern im Nebel los...

              Dann versuch ich mal, auch die Where-Klausel umzuschreiben:

                
                Where  
                  Person.Vorname LIKE ("%" + @vorname + "%") AND  
                  Person.Nachname LIKE ("%" + @nachname + "%") AND  
                  (  
                    (@Zielgruppe1 = -1) OR  
                    (Zielgruppen.ID = @Zielgruppe1) OR  
                    (Zielgruppen.ID = @Zielgruppe2) OR  
                    (Zielgruppen.ID = @Zielgruppe3) OR  
                    (Zielgruppen.ID = @Zielgruppe4) OR  
                    (Zielgruppen.ID = @Zielgruppe5)  
                  ) AND  
                  (  
                    (Konditionen.Preis >= @minPreis OR @minPreis = -1) AND  
                    (Konditionen.Preis <= @maxPreis OR @maxPreis = -1 )  
                  ) AND  
                  (Konditionen.Konzeptionstage <= @vorbereitungszeit OR @vorbereitungszeit = -1) AND  
                  (Spieler.inaktiv <= @inaktiv) AND  
                  (dbo.FuncSpielerDurchschnittAritm(Spieler.ID) >=  @durchschnitt) AND  
                  (Mannschaft.Name LIKE ("%" + @mannschaftName + "%")) AND  
                  (  
                    AnprechpartnerPersonen.Nachname LIKE ("%" + @ansprechpartner + "%") OR  
                    @ansprechpartner = ''  
                  ) AND  
                  (  
                    (@sportart1 =  'default') OR  
                    (Sportarten.ID = @sportart1) OR  
                    (Sportarten.ID = @sportart2) OR  
                    (Sportarten.ID = @sportart3) OR  
                    (Sportarten.ID = @sportart4) OR  
                    (Sportarten.ID = @sportart5)  
                  ) AND  
                  (  
                    (@verhandelbar = 2) OR  
                    (@verhandelbar = Konditionen.Verhandelbar)  
                  )  
              
              

              Zur Erklärung:
              Dieser SQL ist Teil einer Prozedur, in denen alle der Prozedur übergebenen Werte mit @ angeprochen werden.
              Die Prozedur wird durch ein Suchformular aufgerufen, in dem speziell gefiltert gesucht werden kann.
              In diesem Fall kann man sich vorstellen, dass ein großer Verein für die Mannschaftsplanung Spieler suchen und die dann unter Vertrag nehmen kann.

              • Zielgruppe und Sportart sind Multiple-Choice-Selectboxen.
              • dbo.FuncSpielerDurchschnittAritm ist eine MSSQL-Funktion, die die Bewertung des Spielers ausrechnet und die Gesamtbewertung zurückgibt.

              Zum Test gebe ich ausschließlich @mannschaftsName (also das entsprechende Formularfeld) an, indem ich dort einen Namen eingebe, unter dem ich Mannschaften finden müsste, aber keine zugehörigen Spieler.

              Kann man dort den Fehler erkennen?

              MfG
              Rainer

              1. Hello,

                Kann man dort den Fehler erkennen?

                ja, wahrscheinlich: alle Bedingungen sind mit AND verknüpft. Person.Vorname ist eines der Kriterien, das fehlschlagen wird, weil NULL nicht LIKE '%%' entspricht, auf NULL müsste man explizit mit IS NULL prüfen, sprich OR IS NULL. Selbiges gilt für andere Felder.

                MfG
                Rouven

                --
                -------------------
                sh:| fo:} ch:? rl:( br:& n4:{ ie:| mo:} va:) js:| de:] zu:| fl:( ss:) ls:& (SelfCode)
                Ambition is the last refuge of failure.  --  Oscar Wilde (Irish Poet, Novelist, Dramatist and Critic, 1854-1900)