steffen: Postgres Abfrage Problem

Hallo Forumleser,

ich bin derzeit mit meinem Latein am Ende.

Ich habe 2 Tabellen

role
--
id
name

und

role2user
--
id
fk_role
fk_user

in der tbl.role befindet sich folgende einträge:

1 | Admin
2 | User
3 | Support

tbl.role2user hat:

1 | 1 | 1
1 | 3 | 1
1 | 2 | 2

Nun möchte ich ein Abfrage, die mir anhand der userid (zB 1 oder 2) anzeigt, welche rollen verteilt wurden oder noch nicht verteilt wurden. Bei userid 1 sollte als ergebnis kommen:

Rollen die der User hat

role.id | role.name
1 | Admin
3 | Support

Rollen die der User nicht hat

role.id | role.name
2 | User

Könnt ihr mir bitte helfen bei der Abfrage?

mfg steffen

  1. Hallo,

    in der tbl.role befindet sich folgende einträge:

    id| name
      -----------

    1 | Admin
    2 | User
    3 | Support

    tbl.role2user hat:

    id | fk_role | fk_user
      ----------------------

    1 |    1    |    1
    1 |    3    |    1
    1 |    2    |    2

    Nun möchte ich ein Abfrage, die mir anhand der userid (zB 1 oder 2) anzeigt, welche rollen verteilt wurden oder noch nicht verteilt wurden. Bei userid 1 sollte als ergebnis kommen:

    Rollen die der User hat

    role.id | role.name

    1 | Admin
          3 | Support

    Dies löste ich mit einem INNER JOIN

    Gib mir die Spalten
        id,
        name
    aus der Tabelle
        role
    die verknüpft ist mit der Tabelle
        role2user
    über
        gleiche Werte in den Spalten id der Tabelle role und fk_role in role2user
    wobei nur die Datensätze interessieren
        bei denen in der Tabelle role2user die Spalte fk_user den Wert 1 hat

    Alternativ könntest Du ein Subselect verwenden, was den Charme hat, dass Du damit den gleichen Lösungsweg hast wie für folgende Aufgabe:

    Rollen die der User nicht hat

    role.id | role.name
    2 | User

    Gib mir die Spalten
        id,
        name
    aus der Tabelle role
    wobei nur die Datensätze mit den id-Werten interessieren
        die nicht in der Liste der fk_role-Werte
            in der Tabelle role2user
        vorkommen
        wobei nur die Datensätze interessieren
            bei denen in der Tabelle role2user die Spalte fk_user den Wert 1 hat

    Die WHERE-Klausel schriebest Du somit zu:

    WHERE role.id NOT IN (  
        SELECT  
            fk_role  
        FROM  
            role2user  
        WHERE  
            fk_user = 1  
    )
    

    Mit einer leichten Abwandlung in der fünften Zeile kannst Du damit auch Teil 1 erledigen: lasse einfach "nicht" weg:

    Gib mir die Spalten
        id,
        name
    aus der Tabelle role
    wobei nur die Datensätze mit den id-Werten interessieren
        die in der Liste der fk_role-Werte                    -- geändert!
            in der Tabelle role2user
        vorkommen
        wobei nur die Datensätze interessieren
            bei denen in der Tabelle role2user die Spalte fk_user den Wert 1 hat

    Freundliche Grüße

    Vinzenz

    1. Vielen Dank :)

      Klappt wunderbar hier die Abfrage nochmal:

      SELECT  
        a.*  
      FROM  
        t_role a  
      WHERE a.id IN (  
      	SELECT  
      	 fk_role  
      	FROM  
               t_role2user  
      	WHERE  
               fk_user = 21);
      

      Sowie

      SELECT  
        a.*  
      FROM  
        t_role a  
      WHERE a.id NOT IN (  
      	SELECT  
      	 fk_role  
      	FROM  
               t_role2user  
      	WHERE  
               fk_user = 21);
      

      steffen

  2. moin,

    Nun möchte ich ein Abfrage, die mir anhand der userid (zB 1 oder 2) anzeigt, welche rollen verteilt wurden oder noch nicht verteilt wurden. Bei userid 1 sollte als ergebnis kommen:

    kannst du mit einer abfrage machen, indem du einen OUTER JOIN einsetzt. deine vorgabe ist, du willst eh alle rolle haben, unabhängig oder user sie hat oder nicht. also fägnst du mit der tabelle an.

    SELECT r.id, r.name
    FROM role r
    ;

    dann bindest du die user über einen OUTER JOIN mit ein.

    SELECT r.id, r.name, ru.fk_user
    FROM role r
    LEFT JOIN role2user ru ON ru.fk_role = r.id AND ru.fk_user = 1
    ;

    bei allen datensätzen, wo ru.fk_user nicht NULL, sondern 1 ist, diese rolle hat her und analog dazu, wo das Feld NULL ist, die hat er nicht.

    Ilja