Announcement

Collapse
No announcement yet.

Anfrage mit select negieren ?

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

  • Anfrage mit select negieren ?

    Ich weiß der Titel is doof gewählt aber mir viel nichts besseres ein, das man unter 100 Wörtern noch verständlich formulieren könnte.

    Ich hab des Problem, dass ich jetzt auf einer Tabelle "products" mir alle Produkte holen möchte, die in einer Tabelle "gview" einem bestimmten Automatentypen noch nicht zugeordnet sind. Is n bischen verzwickt und meine SQL Kenntnisse kommen da etwas an ihre Grenzen.

    Ich zeig euch mal, was ich mir gebastelt hab und erläutere das Problem.

    select pdid, pdname from products
    where NOT pdid = (select p.pdid from products p, gview g where g.amtid = 10015 and p.pdid = g.pdid group by p.pdid)
    group by PDNAME, PDID

    Mein versuch war für die negierung mir alle IDs zu holen die ich nicht haben möchte, das hätte es auch schon sein können, wenn das überhaupt funktionieren würde. Ich hab es einfach mal versucht abzusetzen, obwohl ich mir schon denken konnte, dass das nicht funktioniert.

    Problem is jetz wohl einfach das nur die erste ID, die das Select zurück gibt auf verwendet wird. Bis dahin funktioniert das auch, aber die zweite ID kann dann nicht mehr berücksichtigt werden.

    Hab ihr jetz ne Idee, wie ich das bewerkstelligen könnte.

    Ich danke für Tips...

  • #2
    Originally posted by Schneidi View Post
    Ich weiß der Titel is doof gewählt aber mir viel nichts besseres ein, das man unter 100 Wörtern noch verständlich formulieren könnte.

    Ich hab des Problem, dass ich jetzt auf einer Tabelle "products" mir alle Produkte holen möchte, die in einer Tabelle "gview" einem bestimmten Automatentypen noch nicht zugeordnet sind. Is n bischen verzwickt und meine SQL Kenntnisse kommen da etwas an ihre Grenzen.

    Ich zeig euch mal, was ich mir gebastelt hab und erläutere das Problem.

    select pdid, pdname from products
    where NOT pdid = (select p.pdid from products p, gview g where g.amtid = 10015 and p.pdid = g.pdid group by p.pdid)
    group by PDNAME, PDID

    Mein versuch war für die negierung mir alle IDs zu holen die ich nicht haben möchte, das hätte es auch schon sein können, wenn das überhaupt funktionieren würde. Ich hab es einfach mal versucht abzusetzen, obwohl ich mir schon denken konnte, dass das nicht funktioniert.

    Problem is jetz wohl einfach das nur die erste ID, die das Select zurück gibt auf verwendet wird. Bis dahin funktioniert das auch, aber die zweite ID kann dann nicht mehr berücksichtigt werden.

    Hab ihr jetz ne Idee, wie ich das bewerkstelligen könnte.

    Ich danke für Tips...

    hallo,

    Versuch mal folgendes (musst du anpassen...)

    Code:
    select * from mytable where id not in (select id from myOthertable)
    /

    Gruss

    Comment


    • #3
      Hmmm.... ahhh.... sehr schön

      Hat genau das gewünschte ergebnis gebracht. Dank dir.

      Also bedeutet "where id NOT IN (select...)", dass das NOT IN die Komplette Rückgabe durchleuchtet ?

      Comment


      • #4
        Also bedeutet "where id NOT IN (select...)", dass das NOT IN die Komplette Rückgabe durchleuchtet ?
        Nein. NOT IN ist nicht das Gegenteil von IN.
        IN wird von Oracle intern mit OR Verknüpfungen aufgelöst:
        Code:
        spalte =wert1
        OR spalte=wert2
        OR spalte=wert3
        OR...
        NOT IN wird aber mit einer AND Verknüpfung aufgelöst:
        Code:
        spalte <>wert1
        AND spalte <>wert2
        AND spalte <>wert3
        AND...
        Dann muss man auch noch sehen, dass eine Datenbank nicht nur TRUE oder FALSE kennt, sondern auch noch NULL - undefiniert. Hast Du also in deiner Subquery deines NOT NULL auch nur einen NULL Wert, ist die gesamte Menge weder TRUE noch FALSE sondern NULL und Du bekommst überhaupt keinen Wert mehr zurück.

        Sicher umgehen kann man das physikalisch mit einem NOT NULL Constraint, oder wenn man, falls dies nicht möglich ist, die Verwendung von NOT EXISTS in Erwägung zieht:
        Code:
        SELECT DISTINCT pdid, pdname 
         FROM products p
        WHERE NOT EXISTS  (SELECT 1 
                             FROM gview g 
                            WHERE g.amtid = 10015 
                              AND p.pdid = g.pdid )
        Des weiteren noch eine Frage: was bezweckst Du mit deinem GROUP BY? Ein GROUP BY muss zum einen immer alle Spalten berücksichtigen, die nicht in einer Aggregatsfunktion auftauchen (es gibt alte mysql versionen, die diesen Fehler unterdrücken und selbst herumzaubern), zum anderen würde ein GROUP BY ohne Aggregatsfunktion identisch mit einem SELECT DISTINCT wirken mit dem Unterschied, dass derjenige der das SQL ließt sofort weiß was Du damit bezwecken möchtest.

        Comment


        • #5
          Hallo TomT,
          Originally posted by TomT View Post
          ...Nein. NOT IN ist nicht das Gegenteil von IN.
          Unter Vernachlässigung der speziellen Logik von NULL-Werten stimmt dieses Aussage nicht!
          Rein logisch ist sie das nämlich schon und den Beweis dafür lieferst du selbst:
          Originally posted by TomT View Post
          IN wird von Oracle intern mit OR Verknüpfungen aufgelöst:
          ...
          NOT IN wird aber mit einer AND Verknüpfung aufgelöst:
          Wenn also A IN (B, C) bedeutet: A = B OR A = C, dann ist: A NOT IN (B, C) gleichzusetzen mit: NOT (A = B OR A = C). Nach logischen Regeln umgeschrieben ist das aber nichts anderes als: NOT (A = B) AND NOT (A = C) oder anders A <> B AND A <> C. Und das ist der Vergleich den die DB durchführt.

          Was den Unterschied ausmacht ist die logische Behandlung von NULL-Werten. Eine UND-Verknüpfung mit einem NULL ist immer NULL, ebenso wie die Negierung (NOT) und der direkte Vergleich (=) von und mit NULL immer NULL ist, während eine ODER-Verknüpfung FALSE, TRUE oder NULL sein kann. Ein Ergebnis NULL wird dann immer wie FALSE gewertet.
          Wenn die abgefragte Menge (B, C) also mindestens einen NULL-Wert enthält, dann stimmt deine obige Aussage, weil gilt:

          A = B OR A = NULL => A = B OR NULL => A = B => kann FALSE / TRUE sein.

          Rein logisch wäre die Umkehrung also TRUE / FALSE. Ist sie aber nicht weil:

          NOT (A = B) AND NOT (A = NULL) => NOT (A = B) AND NOT (NULL) => (A = B) AND NULL => NULL und damit immer FALSE ist!

          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


          • #6
            OK...
            Das war jetz doch etwas viel auf einmal
            Bin noch nicht so der SQL Crack, von daher hab ich das jetz nicht so ganz verstanden, aber ok, ich werd das erstmal sacken lassen und es auch mal mit dem Beispiel von TomT probieren.

            Ich danke euch erstmal für die Hilfestellung.

            PS: Das Group hatte ich dann vergessen, das hatte in dem Statement garkeinen Sinn, mehr.
            Aber ursprünglich sollte das natürlich mal dafür sorgen, dass ich jedes Produkt nur einmal bekomme, aber ich geb die Recht, mit dem Destinct macht es sich wohl doch leichter.

            Mein Fehler.
            Zuletzt editiert von Schneidi; 28.05.2009, 13:05.

            Comment


            • #7
              Unter Vernachlässigung der speziellen Logik von NULL-Werten stimmt dieses Aussage nicht!
              NULL Werte wollte ich genau nicht vernachlässigen. Aber es stimmt ich hätte das noch explizit erwähnen sollen.

              Comment

              Working...
              X