Announcement

Collapse
No announcement yet.

Bedingungen über mehrere Tabelle hinweg

Collapse
X
  • Filter
  • Time
  • Show
Clear All
new posts

  • Bedingungen über mehrere Tabelle hinweg

    Um herauszufinden, welche Menüpunkte ein Benutzer sehen darf, brauche ich eine Datenbankabfrage.

    Tabelle pages
    page: id der Seite
    foo: ein Abfragekriterium
    status: gibt an, ob die Seite öffentlich (status 0 oder 1) oder nur mit Berechtigung sichtbar ist (status 2). Ein Status von -1 bedeutet, dass die Seite nie zu sehen ist.

    Tabelle authorisations
    admin: gibt die id des Benutzers an
    page: die Seitenid für die diese Berechtigung gilt
    type: gibt an, ob der Benutzer die Seite sehen (type=1) oder bearbeiten darf (type=2)

    Bsp:
    admin | page | type
    1 | 12 | 1
    1 | 13 | 2
    2 | 12 | 1
    (Wie macht man hier Tabellen?)
    Dies gibt an, dass Benutzer 1 Seite 12 und 13 ansehen darf, Benutzer 2 aber nur Seite 12.

    Ein Eintrag mit type=0 steht genauso wie ein fehlender Eintrag für kein Recht zum Ansehen.

    So nun zum eigentlichen Problem:

    Ich möchte nun alle Seiten finden, die ein bestimmtes Abfragekriterium erfüllen und für die das Recht zum Ansehen an den aktuellen Benutzer vergeben wurde.
    Also:
    SELECT * FROM pages WHERE foo=bar

    Nun gibt es zwei Fälle für die Berechtigung:
    - status ist 0 oder 1 -> ausgeben
    - status ist 2 -> nur ausgeben, wenn entsprechende Berechtigung erteilt wurde

    Da man also hier zwei Tabellen betrachten muss, habe ich einen JOIN verwendet

    SELECT * FROM pages LEFT JOIN privileges ON pages.page=privileges.page WHERE foo=bar AND (status=0 OR status=1 OR (status=2 AND admin=xyz AND type>0))

    Nun bleibt die Ausgabe aber zum Beispiel leer, wenn für eine Seite gar kein Recht vergeben wurde.


    Stimmt mein Ansatz überhaupt?
    Kann man das effizienter machen?
    Wie bekomme ich das beschriebene Problem in den Griff?

    Danke schonmal im Voraus

    Sloothword

  • #2
    Hallo,

    Versuchs mal so:

    SELECT * FROM pages, privileges WHERE foo=bar
    and pages.page=privileges.page
    AND (status=0 OR status=1 OR (status=2 AND admin=xyz AND type>0))
    docendo discimus

    Comment


    • #3
      Irgendwie hilft des mir auch nicht weiter:

      Ein "SELECT * FROM pages, privileges" gibt mir bei leerer privileges-Tabelle auch ein leeres Resultat.

      Mit einem "SELECT * FROM pages LEFT JOIN PRIVILEGES ON pages.page = privileges.page" bekomm ich bei leerer Tabelle privileges ein Resultat, dass dem SELECT * FROM pages entspricht und die drei restlichen Felder sind mit NULL gefüllt.

      Zweites kommt dem, was ich brauch schon näher.

      Comment


      • #4
        Dann sollte man den impliziten (Inner-)Join durch eine expliziten left (Outer-)Join ersetzen
        [highlight="sql"]
        SELECT
        pa.*,pr.*
        FROM
        pages pa
        left join privileges pr on pr.page = pa.page
        WHERE
        foo=bar and
        (status=0 OR status=1 OR (status=2 AND admin=xyz AND type>0))
        [/highlight]

        Comment


        • #5
          Danke euch allen.

          @Markus Kinzler: Wie unterscheidet sich dein SQL-Code von dem im Eingangspost erwähnten?

          @frauwue: Nein, ohne LEFT JOIN komm ich hier nicht aus, da ich sonst bei leerer privileges-Tabelle nicht einmal mehr die pages-Tabelle bekomm

          Mein Fehler lag letzendlich ganz woanders *schäm*:

          Mein Resultat war nicht leer, nur die Spalte page war leer. MySQL wusste wahrscheinlich nicht, ob die Spalte aus pages oder privileges kommen sollte :-(
          Dachte bei pages.page=privileges.page ist des egal. Deshalb hats acuh immer funktioniert, als privileges noch gut gefüllt war (jede Seite besetzt).

          Comment

          Working...
          X