Oli: JOIN falls Verknüpfung vorhanden

Hallo Leute,

ich komme mit meiner Abfrage nicht weiter:

Ich habe zwei Tabellen User und Bilder

---------------------------
ID User
1  Anna
2  Bernd
3 Chis

---------------------------
Tab Bilder
id_user bild_name sort

1  anna1.jpg 1
1  anna2.jpg 2
2  bernd.jpg 1
---------------------------

SELECT
 user.name,
 bilder.bild_name
FROM
 user,
 bilder
WHERE
 user.id_user = bilder.id_user

...bekomme ich nur User, die ein Bild haben (ist ein OUTER JOIN oder?)

mache ich das ganze mit LEFT JOIN
 LEFT JOIN $bilder ON user.id_user = bilder.id_user

bekomme ich lie Liste der Bilder

---------------------------
Anna  anna1.jpg
Anna  anna2.jpg
Bernd  bernd.jpg
Chris -
---------------------------

ich hätte als Ausgabe jetzt gerne eine Liste aller User und falls sie ein Bild haben das derste Bild (sort=1) dazu

---------------------------
Anna  anna1.jpg
Bernd  bernd.jpg
Chris -
---------------------------

schön wäre auch eine Variante mit in der ich die Bild, falls mehrere als array zurückbekomme, könnte ich in PHP wieder auseinanderfummeln
---------------------------
Anna  anna1.jpg, anna2.jpg
Bernd  bernd.jpg
Chris -
---------------------------

  1. Hi !

    SELECT
    user.name,
    bilder.bild_name
    FROM
    user,
    bilder
    WHERE
    user.id_user = bilder.id_user

    ...bekomme ich nur User, die ein Bild haben (ist ein OUTER JOIN oder?)

    mache ich das ganze mit LEFT JOIN
    LEFT JOIN $bilder ON user.id_user = bilder.id_user

    bekomme ich lie Liste der Bilder


    Anna  anna1.jpg
    Anna  anna2.jpg
    Bernd  bernd.jpg
    Chris -

    ...

    schön wäre auch eine Variante mit in der ich die Bild, falls mehrere als array zurückbekomme, könnte ich in PHP wieder auseinanderfummeln

    Anna  anna1.jpg, anna2.jpg
    Bernd  bernd.jpg
    Chris -

    Also, Du hast die Elemente als LISTE in Deiner Bank. Somit bekommst Du sie auch als LISTE wieder heraus. Was spricht also dagegen, die LISTE einzulesen und in Deinem PHP-Skript das Array damit aufzubauen ?

    Gruß

    Hans

    1. hi,

      Also, Du hast die Elemente als LISTE in Deiner Bank. Somit bekommst Du sie auch als LISTE wieder heraus. Was spricht also dagegen, die LISTE einzulesen und in Deinem PHP-Skript das Array damit aufzubauen ?

      Da spricht natürlich genau so wenig (oder viel?) dagegen, wie dagegen, heutzutage noch durch Aneinanderklopfen von Steinen Feuer machen zu wollen, mit Hammer und Meißel einen Brief "in Stein" zu schreiben, etc.

      gruß,
      wahsaga

      --
      /voodoo.css:
      #GeorgeWBush { position:absolute; bottom:-6ft; }
    2. mache ich das ganze mit LEFT JOIN
      LEFT JOIN $bilder ON user.id_user = bilder.id_user

      bekomme ich lie Liste der Bilder


      Anna  anna1.jpg
      Anna  anna2.jpg
      Bernd  bernd.jpg
      Chris -

      Also, Du hast die Elemente als LISTE in Deiner Bank. Somit bekommst Du sie auch als LISTE wieder heraus. Was spricht also dagegen, die LISTE einzulesen und in Deinem PHP-Skript das Array damit aufzubauen ?

      naja ich könnte wohl mit PHP abfragen if ($name_alt != $name_neu) ...

      halte ich aber nicht für sinnvoill mir die ganzen Daten aus der DB zu holen und in PHP wieder wegzuwerfen. Ich brauch zu jedem User ja nur das erste Bild, falls vorhanden (und nicht die restlichen 25).

      Oli

  2. Hallo Oli,


    ID User
    1  Anna
    2  Bernd
    3 Chis


    Tab Bilder
    id_user bild_name sort

    1  anna1.jpg 1
    1  anna2.jpg 2
    2  bernd.jpg 1

      
    
    > SELECT  
    >  user.name,  
    >  bilder.bild_name  
    > FROM  
    >  user,  
    >  bilder  
    > WHERE  
    >  user.id_user = bilder.id_user  
    
    

    arrgh, diese häßlichen impliziten Joins. Da sträuben sich alle noch vorhandenen Haare. Bitte lies

    Einführung Joins

    ...bekomme ich nur User, die ein Bild haben (ist ein OUTER JOIN oder?)

    mache ich das ganze mit LEFT JOIN
    LEFT JOIN $bilder ON user.id_user = bilder.id_user

    bekomme ich lie Liste der Bilder


    Anna  anna1.jpg
    Anna  anna2.jpg
    Bernd  bernd.jpg
    Chris -

    Ja das ist so, und das ist richtig so.

    ich hätte als Ausgabe jetzt gerne eine Liste aller User und falls sie ein Bild haben das derste Bild (sort=1) dazu


    Anna  anna1.jpg
    Bernd  bernd.jpg
    Chris -

    Du suchst die korrelierenden Unterabfragen. Siehe z.B. Rouvens Archivposting. Die meisten Datenbankmanagementsyste (DBMS) kommen mit solchen Abfragen zurecht, das weit verbreitete MySQL jedoch leider erst ab der Version 4.1.

    Bitte nenne uns daher Dein DBMS, inklusive Version.

    Freundliche Grüße

    Vinzenz

    1. Hallo Vinzenz Mai,


      ID User
      1  Anna
      2  Bernd
      3 Chis


      Tab Bilder
      id_user bild_name sort

      1  anna1.jpg 1
      1  anna2.jpg 2
      2  bernd.jpg 1

      SELECT
      user.name,
      bilder.bild_name
      FROM
      user,
      bilder
      WHERE
      user.id_user = bilder.id_user

      
      >   
      > arrgh, diese häßlichen impliziten Joins. Da sträuben sich alle noch vorhandenen Haare. Bitte lies  
      >   
      > [Einführung Joins](http://aktuell.de.selfhtml.org/artikel/review/datenbanken/joins/)  
        
        
      ähmm  
      ~~~sql
        
      SELECT  
       user.name,  
       bilder.bild_name  
      FROM  
       user,  
       bilder  
      INNER JOIN user  
      ON user.id_user = bilder.id_user  
      
      

      ... wäre besser? Sorry wenn ich so blöd frage :-)

      ...bekomme ich nur User, die ein Bild haben (ist ein OUTER JOIN oder?)

      mache ich das ganze mit LEFT JOIN
      LEFT JOIN bilder ON user.id_user = bilder.id_user
      bekomme ich lie Liste der Bilder


      Anna  anna1.jpg
      Anna  anna2.jpg
      Bernd  bernd.jpg
      Chris -


      Anna  anna1.jpg
      Bernd  bernd.jpg
      Chris -

      Bitte nenne uns daher Dein DBMS, inklusive Version.

      ja sorry das habe ich vergessen: MySQL 4.1.14

      Oli

      1. Hallo Oli,


        ID User
        1  Anna
        2  Bernd
        3 Chis


        Tab Bilder
        id_user bild_name sort

        1  anna1.jpg 1
        1  anna2.jpg 2
        2  bernd.jpg 1

        [... leider falscher Join ...]

        ... wäre besser? Sorry wenn ich so blöd frage :-)

        wenn es richtig wäre, dann ja.


        Anna  anna1.jpg
        Bernd  bernd.jpg
        Chris -

        ja sorry das habe ich vergessen: MySQL 4.1.14

        Ja, da gehen die von mir angesprochenen Subselects.
        Du suchst das Minimum der Spalte Sort, ein erster Ansatz wäre somit folgender ungetestes Statement:

          
        SELECT  
          user.name,  
          b1.bild_name  
        FROM  
          user  
        -- Da Du zweimal auf die Tabelle bilder zugreifen musst,  
        -- führen wir einen Aliasnamen ein.  
        LEFT JOIN bilder b1  
        ON user.id_user = b1.id_user  
        -- Nun suchen wir genau das richtige Bild aus, das ist dasjenige  
        -- mit dem kleinsten Eintrag in der Spalte `sort`  
        WHERE bilder.sort = (SELECT MIN(sort) FROM bilder b2 WHERE b1.id = b2.id)  
        
        

        Freundliche Grüße

        Vinzenz

        1. SELECT
            user.name,
            b1.bild_name
          FROM
            user
          -- Da Du zweimal auf die Tabelle bilder zugreifen musst,
          -- führen wir einen Aliasnamen ein.
          LEFT JOIN bilder b1
          ON user.id_user = b1.id_user
          -- Nun suchen wir genau das richtige Bild aus, das ist dasjenige
          -- mit dem kleinsten Eintrag in der Spalte sort
          WHERE bilder.sort = (SELECT MIN(sort) FROM bilder b2 WHERE b1.id = b2.id)

          
          >   
            
          Hallo Vinzenz  
            
          klappt auf die Schnelle nicht, gibt eine SQL Fehlermeldung aber schon mal ein Ansatz.  
            
          Vielen Dank  
          Oli
          
          1. Hallo Oli,

            hier korrigiertes funktionierendes SQL-Statement:

            Tab user

            ID User
            1  Anna
            2  Bernd
            3 Chis

            Tab Bilder
            id_user bild_name sort

            1  anna1.jpg 1
            1  anna2.jpg 2
            2  bernd.jpg 1

            1. Schritt:
            Zeige mir alle User an, dazu die Bildnamen, sofern welche existieren

              
            SELECT  
                user.user,  
                b1.bild_name  
            FROM user  
            LEFT JOIN bilder b1      -- LEFT JOIN, damit auch die User angezeigt werden,  
                                     -- für die kein Bildeintrag existiert  
                                     -- b1 ist ein Aliasname für den Tabellennamen bilder  
                                     -- Wir greifen später ein zweites Mal auf die Tabelle zu.  
            ON user.id = b1.id_user  -- JOIN-Bedingung  
            
            

            Ergebnis:

            user    bild_name
            -----------------------------------
            Anna    anna1.jpg
            Anna    anna2.jpg
            Bernd   bernd.jpg
            Chris   NULL

            2.Schritt:
            Schränke die Ausgabe auf das Bild ein, das in der Spalte sort den kleinsten Wert aufweist.

              
            SELECT  
                user.user,  
                b1.bild_name  
            FROM user  
            LEFT JOIN bilder b1      -- LEFT JOIN, damit auch die User angezeigt werden,  
                                     -- für die kein Bildeintrag existiert  
                                     -- b1 ist ein Aliasname für den Tabellennamen bilder  
                                     -- Wir greifen später ein zweites Mal auf die Tabelle zu.  
            ON user.id = b1.id_user  -- JOIN-Bedingung  
            WHERE b1.sort = (  
                SELECT MIN(b2.sort)  -- Nur die Datensätze mit dem kleinsten sort-Wert  
                FROM bilder b2  
                WHERE b2.id_user = b1.id_user)  -- bei gleichem user (id_user)  
            
            

            Das Ergebnis

            user    bild_name
            -----------------------------------
            Anna    anna1.jpg
            Bernd   bernd.jpg

            kann noch nicht zufrieden stellen. Zwar wird wie gewünscht bei Anna nur das Bild mit dem kleinsten sort-Wert angezeigt, dafür ist der Eintrag von Chris verlorengegangen. Dies liegt daran, dass für Chris in der Spalte b1.sort der Wert NULL steht. Diesen Datensatz (und vergleichbare) müssen wir gesondert betrachten. Den Vergleich mit NULL-Werten führt man mit IS NULL durch.

            Schritt 3:

              
            SELECT  
                user.user,  
                b1.bild_name  
            FROM user  
            LEFT JOIN bilder b1      -- LEFT JOIN, damit auch die User angezeigt werden,  
                                     -- für die kein Bildeintrag existiert  
                                     -- b1 ist ein Aliasname für den Tabellennamen bilder  
                                     -- Wir greifen später ein zweites Mal auf die Tabelle zu.  
            ON user.id = b1.id_user  -- JOIN-Bedingung  
            WHERE b1.sort = (  
                SELECT MIN(b2.sort)  
                FROM bilder b2  
                WHERE b2.id_user = b1.id_user)  
                OR b1.sort IS NULL   -- damit auch die User ohne Bild berücksichtigt werden.  
            
            

            liefert das gewünschte Ergebnis

            user    bild_name
            -----------------------------------
            Anna    anna1.jpg
            Bernd   bernd.jpg
            Chris   NULL

            Freundliche Grüße

            Vinzenz