ScaraX: Mysql left join problem

Hi,

also, ich habe 2 Tabellen Liga (ID, name) und Clan_liga (ID, ligaID, clanID)

jetzt möchte ich für einen bestimmten Clan alle Ligen angezeigt bekommen und dazu ein hinweis, ob dieser CLan bereits bei der Liga registriert ist oder nicht

mein bisheriger Ansatz:
SELECT
liga.ID,
liga.name,
clan_liga.clanID,
(clan_liga.ID > 0) as isregistered
FROM
liga left join clan_liga on liga.ID = clan_liga.ligaID
WHERE
clan_liga.clanID = [hier clanID einsetzen]
GROUP BY
liga.ID
ORDER BY
liga.name ASC

damit bekomme ich leider nur die Ligen angezeigt, bei denen der Clan registriert ist, jedoch nicht die anderen...

habs auch schon mit
WHERE
clan_liga.clanID = [hier clanID einsetzen]
or
clan_liga.clanID IS NULL
probiert,
aber da bekommt ich dann nur die ligen, an denen clan 3 registriert ist und die ligen, an denen überhaupt kein clan registriert ist, nicht aber die, an denen nur andere clans (außer clan 3) registriert sind... auch nit das was ich wollte...

ich hätte gerne ein Ergebnis wie folgendes (bei gewähltem clan 3:

ID name clanID isregistered
1 ligaA null 0
2 ligaB 3 1
3 ligaC 3 1
4 ligaD null 0
5 ligaE null 0

ich hoffe jemand kann mir weiterhelfen!

MfG
ScaraX.

  1. Hi,

    damit bekomme ich leider nur die Ligen angezeigt, bei denen der Clan registriert ist, jedoch nicht die anderen...

    ah. Du benötigst einen OUTER JOIN.

    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
    1. Hi,

      damit bekomme ich leider nur die Ligen angezeigt, bei denen der Clan registriert ist, jedoch nicht die anderen...

      ah. Du benötigst einen OUTER JOIN.

      soweit ich weiss gibts das bei mysql aber nicht.. bzw. ein LEFT OUTER JOIN funktioniert genau wie LEFT JOIN... habs damit schon probiert, gibt aber das selbe ergebnis...

      Cheatah

      1. Hi,

        ah. Du benötigst einen OUTER JOIN.
        soweit ich weiss gibts das bei mysql aber nicht..

        dann glaube daran, dass es das gibt. Manchmal ist der Glaube stärker als jedes Wissen.

        bzw. ein LEFT OUTER JOIN funktioniert genau wie LEFT JOIN... habs damit schon probiert, gibt aber das selbe ergebnis...

        Dann benötigst Du vielleicht einen RIGHT OUTER JOIN? Zeilen, zu denen bei einer gejointen Tabelle kein Datensatz existiert, werden bei einem OUTER JOIN ins Resultset übernommen, bei einem INNER JOIN nicht.

        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
  2. Hallo

    also, ich habe 2 Tabellen Liga (ID, name) und Clan_liga (ID, ligaID, clanID)

    jetzt möchte ich für einen bestimmten Clan alle Ligen angezeigt bekommen und dazu ein hinweis, ob dieser CLan bereits bei der Liga registriert ist oder nicht

    mein bisheriger Ansatz:
    SELECT
    liga.ID,
    liga.name,
    clan_liga.clanID,
    (clan_liga.ID > 0) as isregistered
    FROM
    liga left join clan_liga on liga.ID = clan_liga.ligaID
    WHERE
    clan_liga.clanID = [hier clanID einsetzen]
    GROUP BY
    liga.ID
    ORDER BY
    liga.name ASC

    ist eine typische MySQL-Schrott-Anweisung, die jedes andere Datenbankmanagementsystem richtigerweise als syntaktisch falsch zurückweist.

    Du musst nach _allen_ Spalten gruppieren, auf die Du _keine_ Aggregatsfunktion anwendest. Du wendest keine Aggregatsfunktion an, also musst Du nach allen Spalten gruppieren. Noch viel einfacher ist es, die überflüssige GROUP-BY-Klausel einfach zu entfernen.

    ID name clanID isregistered
    1 ligaA null 0
    2 ligaB 3 1
    3 ligaC 3 1
    4 ligaD null 0
    5 ligaE null 0

    ich hoffe jemand kann mir weiterhelfen!

    Deine WHERE-Klausel macht Dir alles kaputt. Du möchtest Werte der "linken" Tabelle zugreifen, die NULL-Werte zurückliefern kann. Verschiebe die WHERE-Klausel daher in die JOIN-Bedingung.

    Weiterhin halte ich es für möglich, dass Du die COALESCE-Funktion in Deiner berechneten Spalte "isregistered" verwenden möchtest.

    Freundliche Grüße

    Vinzenz

    1. Hi,

      das hilft mir leider nicht weiter...

      wenn ich das group by weglasse bekomme ich viel zu viele Ergebniszeilen...
      und mit der Where-Klausel muss ich ja irgendwie eingrenzen bzw irgendwo muss ja erwähnt werden, dass es sich um einen bestimmte Clan handelt...

      der Wert isregistered soll einfach nur anzeigen, ob ein Clan registriert ist oder nicht... also 0 oder 1

      MfG
      ScaraX

      1. Hallo

        das hilft mir leider nicht weiter...

        hast Du es versucht?

        wenn ich das group by weglasse bekomme ich viel zu viele Ergebniszeilen...

        Nein, wieso? Kann ein Clan mehrfach in der gleichen Liga sein? Wohl kaum.

        und mit der Where-Klausel muss ich ja irgendwie eingrenzen bzw irgendwo muss ja erwähnt werden, dass es sich um einen bestimmte Clan handelt...

        Ja, nur nicht in der WHERE-Klausel, sondern in der Join-Bedingung.

        der Wert isregistered soll einfach nur anzeigen, ob ein Clan registriert ist oder nicht... also 0 oder 1

        eben deswegen benötigst Du COALESCE ...

        Gib mir zu jeder Liga
          - die id
          - den Liganamen
          - meinen gewünschten Clan, falls er drin ist, sonst NULL
          - und ob er registriert ist (als 0 oder 1, aber nicht als NULL)
        aufwärts sortiert nach Liganamen

        Ich sehe keinen Grund für GROUP BY.

        Freundliche Grüße

        Vinzenz

        1. Super, danke!

          Habs jetzt folgendermaßen gelößt:

          SELECT
          liga.ID,
          liga.name,
          clan_liga.clanID,
          COALESCE(clan_liga.ID) IS NOT NULL as isregistered
          FROM
          liga left join clan_liga on liga.ID = clan_liga.ligaID and clan_liga.clanID = [clanID]
          ORDER BY
          qcms_liga.name ASC

          funktioniert soweit ganz gut!

          MfG
          ScaraX

        2. Hallo

          wenn ich das group by weglasse bekomme ich viel zu viele Ergebniszeilen...

          Nein, wieso? Kann ein Clan mehrfach in der gleichen Liga sein? Wohl kaum.

          und mit der Where-Klausel muss ich ja irgendwie eingrenzen bzw irgendwo muss ja erwähnt werden, dass es sich um einen bestimmte Clan handelt...

          Ja, nur nicht in der WHERE-Klausel, sondern in der Join-Bedingung.

          der Wert isregistered soll einfach nur anzeigen, ob ein Clan registriert ist oder nicht... also 0 oder 1

          eben deswegen benötigst Du COALESCE ...

          Ein kleines Beispiel:

          Tabelle gremien:

          id | bezeichnung
          ----------------
           1 | Spiel
           2 | SR
           3 | Jugend
           4 | Ausbildung

          Tabelle mitglieder

          id | id_gremium | id_person
          -----------------------------
           1 |          1 | 10
           2 |          1 |  7
           3 |          1 | 15
           4 |          2 |  1
           5 |          2 |  8
           6 |          3 | 10
           7 |          3 |  5
           8 |          4 | 11
           9 |          4 |  7

          Du möchtest nun alle Gremien anzeigen - und ob die Person mit der id 10 diesem Gremium angehört.

            
          SELECT  
              g.id,  
              g.bezeichnung,  
              m.id_person  
          FROM  
              gremien g  
          LEFT JOIN  
              mitglieder m  
          ON  
              g.id = m.id_gremium  
          WHERE  
              m.id_gremium = 10  
          
          

          liefert wegen der speziellen Behandlung von NULL-Werten bei Vergleichen nur folgende Datensätze zurück, die Gremien, denen die Person mit der id 10 angehört:

          id | bezeichnung | id_person
          ----------------------------
           1 | Spiel       | 10
           3 | Jugend      | 10

          Führst Du jedoch die Einschränkung auf die Person mit der id 10 in der Join-Bedingung auf, so erhältst Du alle Gremien:

            
          SELECT  
              g.id,  
              g.bezeichnung,  
              m.id_person  
          FROM  
              gremien g  
          LEFT JOIN  
              mitglieder m  
          ON  
              g.id = m.id_gremium  
          AND  
              m.id_gremium = 10  
          
          

          id | bezeichnung | id_person
          ----------------------------
           1 | Spiel       | 10
           2 | SR          | NULL
           3 | Jugend      | 10
           4 | Ausbildung  | NULL

          Da jede Person einem Gremium maximal einmal angehören kann und wir auf eine bestimmte Person prüfen, wird jedes Gremium auch genau einmal aufgeführt, kein Anlass, das Schlüsselwort DISTINCT oder grausamerweise sogar eine GROUP-BY-Klausel einzubauen.

          Nehmen wir nun noch eine berechnete Spalte mit, die istmitglied heißt:

            
          SELECT  
              g.id,  
              g.bezeichnung,  
              m.id_person,  
              (m.id > 0) AS istmitglied  
          FROM  
              gremien g  
          LEFT JOIN  
              mitglieder m  
          ON  
              g.id = m.id_gremium  
          AND  
              m.id_gremium = 10  
          
          

          so erhalten wir aufgrund der besonderen Behandlung bei Vergleichen mit NULL-Werten:

          id | bezeichnung | id_person | istmitglied
          ------------------------------------------
           1 | Spiel       | 10        | 1
           2 | SR          | NULL      | NULL
           3 | Jugend      | 10        | 1
           4 | Ausbildung  | NULL      | NULL

          das heißt eben _nicht_ die Werte 0 und 1. Die Funktion COALESCE ermöglicht es,  0 statt NULL zu bekommen, denn COALESCE(NULL, 0) ergibt 0, COALESCE(1,0) ergibt jedoch 1:

            
          SELECT  
              g.id,  
              g.bezeichnung,  
              m.id_person,  
              COALESCE(m.id > 0), 0) AS istmitglied  
          FROM  
              gremien g  
          LEFT JOIN  
              mitglieder m  
          ON  
              g.id = m.id_gremium  
          AND  
              m.id_gremium = 10  
          
          

          liefert dagegen:

          id | bezeichnung | id_person | istmitglied
          ------------------------------------------
           1 | Spiel       | 10        | 1
           2 | SR          | NULL      | 0
           3 | Jugend      | 10        | 1
           4 | Ausbildung  | NULL      | 0

          Wende mein Beispiel auf Dein Problem an ...

          Freundliche Grüße

          Vinzenz