Announcement

Collapse
No announcement yet.

Logikfehler bei Select-Abfrage

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

  • Logikfehler bei Select-Abfrage

    Hallo ihr Lieben,

    ich hab da ein Problem und bekomme es gerade einfach nicht gelöst. Mir fehlt der richtige Anstoß wie ich diese Abfrage lösen kann.
    Ich habe 2 Tabellen, einmal die Tabelle Reklamation und einmal die Tabelle Infos.
    Diese sind über Schlüssel miteinander verknüpft. Eine Reklamation kann mehrere Infos haben, eine Info nur eine Reklamation.
    So. Ich möchte alle Reklamationen ausgegeben haben, die in den zugehörigen Infos als Benutzer NICHT "blub" (z.B.) stehen haben.

    Hier mein jetziger SQL-Befehl:

    SELECT DISTINCT R_Handwerkertermin, ...
    FROM reklamationen, reklamationen_info
    WHERE RI_User NOT LIKE '%blub%'
    AND R_GID = RI_R_GID

    So... Wenn ich die Abfrage so benutze, bekomme ich alle Datensätze zurück, da jede Reklamation mindestens eine Info hat, die eben "NOT LIKE blub" ist. Sobald aber ein einziges mal in der Info ein "blub" vorkommt, darf diese Reklamation nicht angezeigt werden.

    Das DISTINCT habe ich benutzt, da mir die Abfrage sonst für jeden zugehrigen INFO-Eintrag eine Reklamation ausspuckt. Ich möchte aber jede Reklamation nur einmal ausgegeben bekommen.

    Ich hoffe ich habe verständlich ausgedrückt, was mein Problem ist.
    Wäre über Denkanstöße sehr dankbar.
    Zuletzt editiert von psychomama; 11.01.2010, 16:59. Reason: Grammatikfehler :p

  • #2
    Hallo und willkommen,

    so wie deine Abfrage formuliert ist, bekommst du das kartesische Produkt der beiden Tabellen, beschränkt nur auf die in der WHERE-Klausel genannten Bedingungen. Du benötigst stattdessen einen OUTER JOIN.

    * alle Reklamationen
    * sofern vorhanden, die dazu gespeicherten Informationen
    * sofern NOT LIKE 'blub'
    Also:
    [highlight=sql]SELECT R_Handwerkertermin, ...
    FROM reklamationen rek
    LEFT JOIN reklamationen_info info
    ON R_GID = RI_R_GID
    WHERE RI_User NOT LIKE '%blub%'[/highlight]
    Näheres siehe [wikibooks] Einführung in SQL: OUTER JOIN und die anderen Kapitel zu JOIN.

    Nebenbei: Code sollte markiert werden mit [highlight=sql] oder wenigstens mit dem #-Button. Spaltennamen, die als Präfix den Tabellennamen andeuten, sind unpraktisch; besser ist ein Tabellen-Alias. Auch das ist im Wikibook erläutert.

    Gruß Jürgen

    Comment


    • #3
      Hallo Jürgen,

      beschränkt nur auf die in der WHERE-Klausel genannten Bedingungen
      Und genau diese Bedingung R_GID = RI_R_GID stellt ein implizietes INNER JOIN dar, von daher ist das SQL Statement völlig korrekt.

      Allerdings entspricht das Statement nicht den Anforderungen, es sollen nur Reklamationen ausgegeben werden, bei denen kein Info-Satz mit blub vorkommt. Das bekommt man am einfachsten mit einem Subselect hin:
      [highlight=SQL]SELECT R_Handwerkertermin, ...
      FROM reklamationen rek
      WHERE NOT R_GIF IN
      (SELECT RI_R_GID
      FROM reklamationen_info
      WHERE RI_User LIKE '%blub%')[/highlight]
      Olaf Helper

      <Blog> <Xing>
      * cogito ergo sum * errare humanum est * quote erat demonstrandum *
      Wenn ich denke, ist das ein Fehler und das beweise ich täglich

      Comment


      • #4
        Hallo,
        Originally posted by O. Helper View Post
        ...Das bekommt man am einfachsten mit einem Subselect hin:
        [highlight=SQL]SELECT R_Handwerkertermin, ...
        FROM reklamationen rek
        WHERE NOT R_GIF IN
        (SELECT RI_R_GID
        FROM reklamationen_info
        WHERE RI_User LIKE '%blub%')[/highlight]
        wobei Subselects mit NOT IN immer mit Vorsicht zu geniesen sind, für den Fall dass NULL-Werte eine Rolle spielen. Ist im Subselect in RI_R_GID auch nur ein NULL enthalten, wird die Gesamte NOT R_GIF IN Abfrage immer NULL und damit False! Besser ist in dem Fall dann ein NOT EXISTS oder ein OUTER JOIN.

        [highlight=SQL]SELECT R_Handwerkertermin, ...
        FROM reklamationen rek
        left join reklamationen_info
        on R_GID = RI_R_GID and RI_User LIKE '%blub%'
        where R_GID IS null[/highlight]

        Gruß Falk
        Wenn du denkst du hast alle Bugs gefunden, dann ist das ein Bug in deiner Denksoftware.

        Quellcode ohne ein Mindestmaß an Formatierung sehe ich mir nicht an! Ich leiste keinen Privatsupport per Mail oder PN!

        Comment


        • #5
          Hallo,

          erst einmal vielen Dank für eure Bemühungen.

          Die Variante mit dem Subselect funktioniert wunderbar. Da bei mir auch keine Gefahr ist, dass ein NULL-Wert eingetragen ist, da diese Spalten Primärschlüssel sind, ist die darauffolgende Variante auch nicht notwendig.
          Allerdings habe ich sie trotzdem aus Interesse ausprobiert und bin dabei auf keinen grünen Zweig gekommen.
          Der letzten Bedingung R_GID IS NULL kann ich nicht ganz folgen. Wenn ich sie auf NOT NULL ändere zeigt er mir einfach komplett alle Datensätze an, als ob er keine Bedingungen hätte.
          Falls ihr noch Zeit und Lust habt, könnt ihr mir das ja nochmal erklären. Wenn nicht, ist es auch nicht schlimm. Ich habe jetzt meine Lösung.
          Danke nochmals an euch.

          Grüsschen

          Comment


          • #6
            Originally posted by psychomama View Post
            ...Falls ihr noch Zeit und Lust habt, könnt ihr mir das ja nochmal erklären.
            Da ich dein DB-Modell nicht kenne und in deinem Bsp. keine explizite Benennung der Felder vorliegt, kann es natürlich auch
            [highlight=sql]
            ...
            where RI_R_GID IS null
            [/highlight]
            heissen. Die Prüfung auf IS NULL muß für das Feld der gejointen Tabelle, also reklamationen_info, erfolgen.
            Hintergedanke:
            Der LEFT JOIN liefert für alle DS, die der JOIN-Bedingung nicht genügen, trotzdem für die Ausgangstabelle Werte, während die gejointen Felder NULL sind. Durch die Prüfung auf IS NULL in der Where-Bedingung (ausserhalb des Join) werden dann nur die DS angezeigt, die die JOIN-Bedingung NICHT erfüllen.

            Gruß Falk

            P.S.: Erfahrungsgemäß ist die JOIN-Lösung - wenn nicht andere Gründe dagegen sprechen - der Variante mit Subselect aus Performance- und Kostengründen vorzuziehen.
            Wenn du denkst du hast alle Bugs gefunden, dann ist das ein Bug in deiner Denksoftware.

            Quellcode ohne ein Mindestmaß an Formatierung sehe ich mir nicht an! Ich leiste keinen Privatsupport per Mail oder PN!

            Comment


            • #7
              Jawoll!
              Jetzt habe ich verstanden, wie das abläuft.
              Habe es ausprobiert und es läuft!
              Vielen Dank für die Erklärung und die Geduld.
              Grüsschen

              Comment

              Working...
              X