jo: Schwieriger Query

Hallo.

Ich habe zwei Tabellen.

user:
id username
1  hans
2  franz
3  ferdinand
4  klaus
5  bernd
6  Fridolin

users_friends:
userone usertwo status
1       2       1
1       5       2
1       6       1
3       4       1
2       1       1

Ich möchte nun dynamisch alle namen haben die mit %tag anfangen aber nur von denen die freunde von hans sind(status 1 haben).

Gegeben ist die Userid 1 von hans und der buchstabe F
Also der Query müsste so lauten:
Suche alle userone und usertwo wo userone=1 oder usertwo=1 und status=1,
nehme dann alle ids die !=1 sind und durchsuche Tabelle users nach den userone und usertwo ids und gebe mir die wieder die mit f% anfangen.

Wie bitte ist das möglich? geht das überhaupt mit einem Query?

Gruß, Jo

  1. Hallo,

    user:
    id username
    1  hans
    2  franz
    3  ferdinand
    4  klaus
    5  bernd
    6  Fridolin

    users_friends:
    userone usertwo status
    1       2       1
    1       5       2
    1       6       1
    3       4       1
    2       1       1

    können die Werte von userone und usertwo überhaupt identisch sein?

    Ich möchte nun dynamisch alle namen haben die mit %tag anfangen aber nur von denen die freunde von hans sind(status 1 haben).

    und wo ist Dein Problem?

    Gegeben ist die Userid 1 von hans und der buchstabe F

    Suche alle userone und usertwo wo userone=1 oder usertwo=1 und status=1,

    nehme dann alle ids die !=1 sind und durchsuche Tabelle users nach den userone und usertwo ids und gebe mir die wieder die mit f% anfangen.

    Nein. Warum möchtest Du diese haben? Ich bin ganz im Gegenteil der Ansicht, Du möchtest folgendes haben:

    Gib mir die eindeutige Liste
        der Benutzernamen
    aus
        der Tabelle user
    die mit der Tabelle users_friends verknüpft ist
        über Gleichheit der Werte in den Spalten id und usertwo
    wobei nur die Werte interessieren
        mit dem Wert 1 in der Spalte userone (sprich Hans)
        und dem Status 1 (d.h. Freund)
    verbunden mit
    der eindeutigen Liste
        der Benutzernamen
    aus
        der Tabelle user
    die mit der Tabelle user_friends verknüpft ist
        über Gleichheit der Werte in den Spalten id und userone(!)
    wobei nur die Werte interssieren
        mit dem Wert 1 in der Spalte usertwo (sprich Hans)
        und dem Status 1 (d.h. Freund)

    Wie bitte ist das möglich? geht das überhaupt mit einem Query?

    Ja sicher: wie Du siehst mit einer UNION zweier Joins und einer WHERE-Klausel.
    Ich gehe davon aus, dass Dein Datenbankmanagementsystem (wie z.B. DB2, Firebird, Informix, MySQL, Oracle, PostgreSQL, MS SQL Server, ...) in der vorhandenen Version diese Basis-SQL-Funktionalität unterstützt.

    Freundliche Grüße

    Vinzenz

    1. Hi.

      Gib mir die eindeutige Liste
          der Benutzernamen
      aus
          der Tabelle user
      die mit der Tabelle users_friends verknüpft ist
          über Gleichheit der Werte in den Spalten id und usertwo
      wobei nur die Werte interessieren
          mit dem Wert 1 in der Spalte userone (sprich Hans)
          und dem Status 1 (d.h. Freund)
      verbunden mit
      der eindeutigen Liste
          der Benutzernamen
      aus
          der Tabelle user
      die mit der Tabelle user_friends verknüpft ist
          über Gleichheit der Werte in den Spalten id und userone(!)
      wobei nur die Werte interssieren
          mit dem Wert 1 in der Spalte usertwo (sprich Hans)
          und dem Status 1 (d.h. Freund)

      Sorry das kan verstehe ich nicht. Was meinst du mit verknüpft ist?
      Ich würde das jetzt so verstheen

      SELECT username
      FROM users
      JOIN users_friends ON users_friends.usertwo=users.id OR users_friends.userone=users.id AND status=1

      Aber wie geht es weiter?

      Gruß, Jo

      1. Hallo Jo,

        verbinde das Ergebnis von

        Gib mir die eindeutige Liste
            der Benutzernamen
        aus
            der Tabelle user
        die mit der Tabelle users_friends verknüpft ist
            über Gleichheit der Werte in den Spalten id und usertwo
        wobei nur die Werte interessieren
            mit dem Wert 1 in der Spalte userone (sprich Hans)
            und dem Status 1 (d.h. Freund)

        verbunden mit

        mit

        der eindeutigen Liste
            der Benutzernamen
        aus
            der Tabelle user
        die mit der Tabelle user_friends verknüpft ist
            über Gleichheit der Werte in den Spalten id und userone(!)
        wobei nur die Werte interssieren
            mit dem Wert 1 in der Spalte usertwo (sprich Hans)
            und dem Status 1 (d.h. Freund)

        Sorry das kan verstehe ich nicht. Was meinst du mit verknüpft ist?

        Verknüpfung: JOIN

        Ich würde das jetzt so verstheen

        SELECT username
        FROM users
        JOIN users_friends ON users_friends.usertwo=users.id OR users_friends.userone=users.id AND status=1

        Nein.

        Verbindung: UNION

        Verbinde mit UNION die Ergebnisse zweier SELECT-Anweisungen

        Freundliche Grüße

        Vinzenz

        1. Hallo Vinzent,

          bitte hilf mir noch ein wenig mehr, ich schaff das so nicht..
          Ich versthee nicht wie das aussehen soll.

          Gruß, Jo

          1. Hallo,

            bitte hilf mir noch ein wenig mehr, ich schaff das so nicht..

            gehen wir zurück zum Start. Du hast folgende zwei Tabellen:

            user:
            id username
            1  hans
            2  franz
            3  ferdinand
            4  klaus
            5  bernd
            6  Fridolin

            users_friends:
            userone usertwo status
            1       2       1
            1       5       2
            1       6       1
            3       4       1
            2       1       1

            Das gewünschte Ergebnis sieht wie folgt aus:

            franz
            Fridolin

            Begründung:
            Gib mir alle Freunde (status = 1) von Hans (d.h. entweder userone ist 1 oder usertwo ist 1). Jeder Freund soll nur ein einziges Mal im Ergebnis aufgeführt werden. Ich bin nur an den Freunden interessiert, deren Name mit "F" beginnt, dabei spielt Groß- und Kleinschreibung keine Rolle.

            Mein Lösungsvorschlag war daher:

            Gib mir die eindeutige Liste
                der Benutzernamen
            aus
                der Tabelle user
            die mit der Tabelle users_friends verknüpft ist
                über Gleichheit der Werte in den Spalten id und usertwo
            wobei nur die Werte interessieren
                mit dem Wert 1 in der Spalte userone (sprich Hans)
                und dem Status 1 (d.h. Freund)
            verbunden mit
            der eindeutigen Liste
                der Benutzernamen
            aus
                der Tabelle user
            die mit der Tabelle user_friends verknüpft ist
                über Gleichheit der Werte in den Spalten id und userone(!)
            wobei nur die Werte interssieren
                mit dem Wert 1 in der Spalte usertwo (sprich Hans)
                und dem Status 1 (d.h. Freund)

            Schauen wir es uns Schritt für Schritt an:

            1. Ermittle alle Freunde von Hans, wenn die User-ID von Hans in der Spalte
               usertwo steht:

            -- Gib mir die Liste  
            SELECT  
            --    der Benutzernamen  
                u.username  
            -- aus  
            FROM  
            --    der Tabelle user  
                user u                   -- die ich mit dem Aliasnamen u anspreche  
            -- die mit der Tabelle users_friends verknüpft ist  
            INNER JOIN  
                users_friends uf         -- mit dem Aliasnamen uf  
            --    über Gleichheit der Werte in den Spalten id und userone  
            ON  
                u.id = uf.userone  
            -- wobei nur die Werte interessieren  
            WHERE  
            --    mit dem Wert 1 in der Spalte usertwo (sprich Hans)  
                uf.usertwo = 1  
            --    und dem Status 1 (d.h. Freund)  
            AND  
                uf.status = 1  
            --     und die mit dem Buchstaben "F" beginnen  
            AND  
                u.username LIKE 'F%'  
            
            

            Diese Abfrage liefert das Ergebnis

            username
            --------
            franz

            (dein letzter Datensatz ist der einzige, der die Bedingungen erfüllt)

            2. Schritt:
            Analog ermitteln wir die Liste der Freunde von Hans, wenn die ID von Hans in
            der Spalte userone steht:

            SELECT  
                username  
            FROM  
                user u  
            INNER JOIN  
                users_friends uf  
            ON  
                u.id = uf.usertwo        -- diesmal ist der Freund in Spalte usertwo  
            WHERE  
                uf.userone = 1           -- nur Freunde von Hans als userone  
            AND  
                uf.status = 1            -- Freunde!  
            AND  
                u.username LIKE 'F%'     -- nur Freunde, deren Name mit "F" beginnt  
            
            

            Diese Abfrage liefert (aus Datensatz 1 und 3)

            username
            --------
            franz
            Fridolin

            3. Schritt:
            Verbinde beide Ergebnismengen mit UNION. Da gleiche Datensätze nur einmal vorkommen dürfen (sprich: franz darf nur einmal vorkommen, nicht zweimal), könnten wir UNION DISTINCT verwenden - da dies das Standardverhalten von UNION ist, können wir DISTINCT einfach weglassen :-)

            SELECT  
                username  
            FROM  
                user u  
            INNER JOIN  
                users_friends uf  
            ON  
                u.id = uf.usertwo  
            WHERE  
                uf.status = 1  
            AND  
                uf.userone = 1  
            AND  
                u.username LIKE 'F%'  
              
            UNION DISTINCT                  -- DISTINCT ist hier optional  
            	  
            SELECT  
                username  
            FROM  
                user u  
            INNER JOIN  
                users_friends uf  
            ON  
                u.id = uf.userone  
            WHERE  
                uf.status = 1  
            AND  
                uf.usertwo = 1	  
            AND  
                u.username LIKE 'F%'  
            AND  
                uf.usertwo = 1	
            

            und erhalten - wie gewünscht:

            username
            --------
            franz
            Fridolin

            Anmerkung: welche der beiden Abfrage als erste genommen wird, spielt keine Rolle :-)

            Freundliche Grüße

            Vinzenz