Problem mit Mehrfach-Feld-Abfrage



  • Ich habe eine Tabelle tG mit 2 Feldern:

    fID gID
    ------------
    415 1
    415 3
    415 9
    415 27
    416 3
    416 28
    417 5
    417 9
    417 21
    417 24
    418 7
    418 18
    418 26
    419 1
    419 7
    419 26
    420 1
    420 9
    420 26
    421 9
    421 18
    421 26
    422 1
    422 3
    422 14
    422 27
    ... ... usw.

    Jetzt wollte ich alle fIDs haben, in denen gID 7 und 18 und 26 ist.

    Die Abfrage

    SELECT     fID, gID
    FROM         tG
    WHERE     (gID = 7) AND (gID = 18) AND (gID = 26)
    

    liefert aber kein Ergebnis obwohl es viele Einträge gibt bei denen solche Einträge vorkommen.

    Kann mir jemand helfen? Vielen Dank! :xmas1:



  • Hallo, das Problem ist, dass dein DBMS die Tabelle durchgeht und das für jedes einzelne Tupel überprüft:(gID = 7) AND (gID = 18) AND (gID = 26)

    Ein bestimmtes Tupel hat aber nur genau eine gID. Das bedeutet, dass die WHERE Bedingung nie erfüllt sein kann.

    Edit: eine Lösung wäre wohl auch interessant :xmas1:

    SELECT     t1.fID
    FROM         tG t1, tG t2, tG t3
    WHERE     (t1.gID = 7) AND (t2.gID = 18) AND (t3.gID = 26) AND t1.fID = t2.fID AND t2.fID=t3.fID
    

    (ungetestet)
    Das ist aber SEHR ineffizient!

    Das dürfte etwas effizienter sein:

    select q.fID
    from (select fID,gID from tG where gID=7 or gID=18 or gID=26) q
    group by fID
    having count(*)>=3;
    

    Eine Annahme ist hier allerdings, dass es keine zwei Tupel gibt, bei denen fID und gID gleich sind.



  • SELECT     fID, gID
    FROM         tG
    WHERE     gID in (7,18,26)
    


  • Wutz, deine Abfrage entspricht aber einem ODER und nicht einem AND.



  • Soso.
    Hast du die erste Antwort über die Sinnlosigkeit der ANDs gelesen?



  • Ja, habe ich. Dies bezog sich aber nur auf die konkrete Abfrage (einen Spaltenwert gleichzeitig auf 3 verschiedene Zahlenwerte abzufragen).
    Der Threadersteller möchte aber alle fId haben, bei denen es einen zugehörigen Eintrag gID mit den Werten (7, 18 und 26) gibt. Und dies läßt sich z.B. mit Gruppierung lösen (s. Antwort von Zebald).



  • Zebald schrieb:

    Eine Annahme ist hier allerdings, dass es keine zwei Tupel gibt, bei denen fID und gID gleich sind.

    Wenn das nicht so ist dann hat er sowieso ein Problem denn es entspricht nicht einem RDBMS wo jeder Datensatz eindeutig identifizierbar sein muss.

    Bei dieser Tabelle müsste ein UNIQUE auf beide Spalten gelegt sein.



  • Ich habe mich vielleicht unverständlich ausgedrückt wenn ich die Antworten lesen.

    Eine fID hat bestimmte gID-Einträge z.B. 7,18,26. Gesucht werden sollen jetzt alle fIDs die ebenfalls diese gID-Einträge enthalten, also auch 7,18,26.

    Ein WHERE IN hatte ich schon versucht, bevor ich hier schrieb. Ist für diesen Zweck unbrauchbar.



  • Gibt es in Deinem obigen Beispiel eine fID für die Du ein nichtleeres Ergebnis bekommen kannst, wenn du Deine gewünschte Abfrage ausführst?



  • Zebald schrieb:

    Gibt es in Deinem obigen Beispiel eine fID für die Du ein nichtleeres Ergebnis bekommen kannst, wenn du Deine gewünschte Abfrage ausführst?

    Wie meinst Du das?



  • ihhDonkey schrieb:

    Zebald schrieb:

    Gibt es in Deinem obigen Beispiel eine fID für die Du ein nichtleeres Ergebnis bekommen kannst, wenn du Deine gewünschte Abfrage ausführst?

    Wie meinst Du das?

    Danit wollte ich Dir letztendlich sagen, dass für Dein Beispiel keine fIDs existieren, für die Deine Aufgabenstellung gilt.



  • Im meinem Beispiel gibt es tatsächlich keinen solchen Fall. In meiner realen Anwendung aber schon. Hier also noch Mal das Problem:

    Eine fID hat bestimmte gID-Einträge z.B. 7,18,26. Gesucht werden sollen jetzt alle fIDs die ebenfalls diese gID-Einträge enthalten, also auch 7,18,26.

    Wer hat eine möglichst effiziente Lösung zu diesem Problem?



  • select fID from tG where gID in(7,18,26) group by fID having count(*)=3
    


  • ihhDonkey schrieb:

    Im meinem Beispiel gibt es tatsächlich keinen solchen Fall. In meiner realen Anwendung aber schon. Hier also noch Mal das Problem:

    Eine fID hat bestimmte gID-Einträge z.B. 7,18,26. Gesucht werden sollen jetzt alle fIDs die ebenfalls diese gID-Einträge enthalten, also auch 7,18,26.

    Wer hat eine möglichst effiziente Lösung zu diesem Problem?

    Hi, ich habe jetzt nicht allzuviel Zeit. Deswegen eine nicht 100%tig durchdachte Query, die das liefert, was ich denke das Du meinst.

    create view asdftest(g1,g2) as  (select distinct x.fID as g1, y.fID as g2
    from te x, te y
    where x.fID <> y.fID and not exists (select a.gID from tG a where a.fID=x.fID and not exists (select b.gID from tG b where y.fID=b.fID and a.gID=b.gID)));
    
    select distinct res.g1 as fID , res.g2 as "fIDs mit genau gleichen gIDs"
    from asdftest res, asdftest res1
    where res.g1=res1.g2;
    

    (kann man natürlich auch zusammenfassen oder mit with formulieren... wahrscheinlich kann man das auch noch vereinfachen und sauberer machen)


Anmelden zum Antworten