Sören: [MySQL] unerklärliche Ausgabe

Guten Abend!

Ich benutze diesen Query:

SELECT up1.rightid FROM user_permissions AS up1 JOIN user_permissions AS up2 ON up1.rightid = up2.rightid JOIN user_permissions AS up3 ON up1.rightid = up3.rightid WHERE up1.groupid = '2' AND up2.groupid <> '1' AND up3.groupid <> '3' LIMIT 0,1

Und diese einfache Datenbank:

id  rightid  groupid
  2   1        1
  3   2        1
  4   2        2

MySQL gibt mir für diesen Query für rightid 2 aus. Eigentlich würde ich kein Ergebnis erwarten!
Wo liegt der Gedankenfehler?

Danke!

  1. Hi Sören.

    MySQL gibt mir für diesen Query für rightid 2 aus. Eigentlich würde ich kein Ergebnis erwarten!

    Abgesehen davon, dass die vielen Anführungszeichen etwas irritieren, weil ich numerische Datentypen erwartet hätte:

    Der Datensatz

    up1.id | up1.rightid | up1.groupid | up2.id | up2.rightid | up2.groupid | up3.id | up3.rightid | up3.groupid
    -------+-------------+-------------+--------+-------------+-------------+--------+-------------+------------
         4 |           2 |           2 |      4 |           2 |           2 |      4 |           2 |           2

    also dreimal der dritte Datensatz Deiner Tabelle, erfüllt alle Bedingungen. Dessen up1.rightid ist 2, und die kriegst Du.

    Wo liegt der Gedankenfehler?

    Keine Ahnung.

    Viele Grüße,
    der Bademeister

    1. Guten Morgen Bademeister

      Abgesehen davon, dass die vielen Anführungszeichen etwas irritieren, weil ich numerische Datentypen erwartet hätte:

      Richtig, Anführungszeichen wurden entfernt

      also dreimal der dritte Datensatz Deiner Tabelle, erfüllt alle Bedingungen. Dessen up1.rightid ist 2, und die kriegst Du.

      Achja Vielen Dank für die Aufklärung.

      Dennoch habe ich hier Programmiernot.

      id  rightid  groupid
        2   1        1
        3   2        1
        4   2        2

      rightid 2 weist hier auf groupid 1 und 2. Ich hätte aber gerne die rightid, die nur auf groupid 2 weist.
      In diesem Fall würde ich also kein Ergebnis erwarten.

      Wäre schön wenn ihr meiner Programmiernot hier etwas beihelfen könntet.
      Danke!

      Gruß Sören

      1. Guten Morgen Bademeister

        Abgesehen davon, dass die vielen Anführungszeichen etwas irritieren, weil ich numerische Datentypen erwartet hätte:

        rightid 2 weist hier auf groupid 1 und 2. Ich hätte aber gerne die rightid, die nur auf groupid 2 weist.

        Hm,
        abgesehen davon, das ich den ursprünglichen Select etwas umfangreich finde, wenn Du nur groupid = 2 haben willst sähe mein Code so aus.
         ... where groupid = 2
        sonstige Bedingungen

        tschüß
        Troll.Soft

        1. id  rightid  groupid
            2   1        1
            3   2        1
            4   2        2

          rightid 2 weist hier auf groupid 1 und 2. Ich hätte aber gerne die rightid, die nur auf groupid 2 weist.

          Was weist hier worauf? Im MySQL-Sinne weist hier nix, so weise ist MySQL nicht ;-) Wenn Du nur den Datensatz haben willst, bei dem rightid 2 und groupid 2 ist, dann sollte das vielleicht als Bedingung in Deinem Statement untergebracht werden.

          Ich dachte man kann sich das so gut vorstellen, aber gut dann versuch ichs anders zu erklären:
          Die oben genannte Tabelle verbindet die Tabelle rights mit groups, mit rightid und groupid perspektivisch.
          In meinem Beispiel ist rightid 2 mit groupid 1 und groupid 2 verbunden.
          Nun möchte ich mit einem Query die rightid herausfinden, bei der die groupid 2 NUR EINE rightid verbindet.

          Ein Beispiel:
          groupid 2 ist mit rightid 2 verbunden, aber rightid 2 ist auch mit groupid 1 verbunden. groupid 2 soll aber eine alleinstehende rightid haben. Also die rightid die auf groupid 2 "zeigt" oder "weist" soll auf keine andere groupid zeigen.

          Da es in meinem obigen Beispiel aber keine rightid gibt, die NUR auf groupid 2 zeigt, gibt der query also kein Ergebnis aus.

          Hm,
          abgesehen davon, das ich den ursprünglichen Select etwas umfangreich finde, wenn Du nur groupid = 2 haben willst sähe mein Code so aus.
          ... where groupid = 2
          sonstige Bedingungen

          Nein der Query würde mir rightid 2 ausgeben, rightid 2 "zeigt" aber auch auf groupid 1 und genau das möchte ich nicht.

          Die einzige Möglichkeit die ich momentan sehe, ist dass ich die tabellen oben solange mit sich selbst verbinde wie es gleiche rightids gibt (also: user_permissions AS up1 JOIN user_permissions AS up2 ON up1.rightid = up2.rightid) und dann in einem where abfrage schaue ob eine groupid gleich 2 ist und die anderen ungleich aller anderen möglichen groupids sind.

          Genau das hab ich mit meinem Query versucht:
          SELECT up1.rightid FROM user_permissions AS up1 JOIN user_permissions AS up2 ON up1.rightid = up2.rightid WHERE up1.groupid = '2' AND up2.groupid <> '1' LIMIT 0,1

          Doch leider nicht mit dem gewünschten Erfolg

          Danke
          Gruß Sören

          1. yo,

            Die oben genannte Tabelle verbindet die Tabelle rights mit groups, mit rightid und groupid perspektivisch.

            also eine typische n:m beziehungstabelle.

            In meinem Beispiel ist rightid 2 mit groupid 1 und groupid 2 verbunden.
            Nun möchte ich mit einem Query die rightid herausfinden, bei der die groupid 2 NUR EINE rightid verbindet.

            du erklärst viel zu kompliziert und darin liegt das problem. die richtige abfrage dafür zu finden ist letzlich sehr leicht. wenn ich dich richtig verstanden habe, willst du von groupid 2 alle rights haben, die ihr alleine zugeordnet sind. hilfreich ist es immer sinnvolle beispiele zu geben, also warum zum beispiel der eine fall nicht trifft, aber vor allem auch ein beispiel, warum es trifft.

            SELECT up.*
            FROM user_permissions up
            WHERE up.groupid = 2
            AND NOT EXISTS (SELECT NULL
                            FROM user_permissions up2
                            WHERE up2.rightid = up.rightid
                            AND up2.groupid <> up.groupid
                           )
            ;

            Ilja

      2. id  rightid  groupid
          2   1        1
          3   2        1
          4   2        2

        rightid 2 weist hier auf groupid 1 und 2. Ich hätte aber gerne die rightid, die nur auf groupid 2 weist.

        Was weist hier worauf? Im MySQL-Sinne weist hier nix, so weise ist MySQL nicht ;-) Wenn Du nur den Datensatz haben willst, bei dem rightid 2 und groupid 2 ist, dann sollte das vielleicht als Bedingung in Deinem Statement untergebracht werden.

        In diesem Fall würde ich also kein Ergebnis erwarten.

        Den von mir gewählten Beispieldatensatz kriegst Du immer noch, bei dem ist das doch erfüllt.

        Kannst Du mal in Worten sagen, was Du eigentlich vorhast?

        Viele Grüße
        der Bademeister

  2. Eigentlich würde ich kein Ergebnis erwarten!

    Warum nicht?

    Wo liegt der Gedankenfehler?

    Das kann man dir erst dann sagen, wenn man deine Gedankengänge kennt.
    Dann kann dir vielleicht auch jemand sagen, wie du die Query vereinfachen könntest. Die sieht nämlich schon ziemlich wirr aus. Was soll die denn bewirken.