| Autor |
Nachricht |
ihhDonkey
Unregistrierter
|
ihhDonkey Unregistrierter
18:41:10 02.12.2011 Titel: |
Problem mit Mehrfach-Feld-Abfrage |
Zitieren |
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
| Code: | SELECT fID, gID
FROM tG
WHERE (gID = 7) AND (gID = 18) AND (gID = 26) | |
| Code: | SELECT fID, gID
FROM tG
WHERE (gID = 7) AND (gID = 18) AND (gID = 26) | |
| Code: | 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: |
|
|
|
 |
Zebald
Mitglied
Benutzerprofil
Anmeldungsdatum: 17.08.2005
Beiträge: 37
|
Zebald Mitglied
20:52:53 02.12.2011 Titel: |
|
Zitieren |
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:
| Code: | 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 | |
| Code: | 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 | |
| Code: | 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:
| Code: | 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; | |
| Code: | 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; | |
| Code: | 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. |
Zuletzt bearbeitet von Zebald am 21:27:22 02.12.2011, insgesamt 4-mal bearbeitet |
|
 |
Wutz
Mitglied
Benutzerprofil
Anmeldungsdatum: 15.04.2010
Beiträge: 2103
|
Wutz Mitglied
23:33:56 03.12.2011 Titel: |
|
Zitieren |
| Code: | SELECT fID, gID
FROM tG
WHERE gID in (7,18,26) | |
| Code: | SELECT fID, gID
FROM tG
WHERE gID in (7,18,26) | |
| Code: | SELECT fID, gID
FROM tG
WHERE gID in (7,18,26) | |
|
_________________ Java, the best argument for Smalltalk since C++. -- Frank Winkler
|
|
 |
Th69
Mitglied
Benutzerprofil
Anmeldungsdatum: 25.03.2008
Beiträge: 2256
|
Th69 Mitglied
17:50:05 04.12.2011 Titel: |
|
Zitieren |
Wutz, deine Abfrage entspricht aber einem ODER und nicht einem AND. |
|
|
|
 |
Wutz
Mitglied
Benutzerprofil
Anmeldungsdatum: 15.04.2010
Beiträge: 2103
|
Wutz Mitglied
19:00:29 04.12.2011 Titel: |
|
Zitieren |
Soso.
Hast du die erste Antwort über die Sinnlosigkeit der ANDs gelesen? |
_________________ Java, the best argument for Smalltalk since C++. -- Frank Winkler
|
|
 |
Th69
Mitglied
Benutzerprofil
Anmeldungsdatum: 25.03.2008
Beiträge: 2256
|
Th69 Mitglied
21:35:26 04.12.2011 Titel: |
|
Zitieren |
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). |
|
|
|
 |
Unix-Tom
Moderator
Benutzerprofil
Anmeldungsdatum: 18.07.2000
Beiträge: 10398
|
Unix-Tom Moderator
07:32:32 05.12.2011 Titel: |
|
Zitieren |
| 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. |
_________________ Moderator für MFC, Linux, C# - NET und Datenbanken
|
|
 |
ihhDonkey
Unregistrierter
|
ihhDonkey Unregistrierter
10:38:52 06.12.2011 Titel: |
|
Zitieren |
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. |
|
|
|
 |
Zebald
Mitglied
Benutzerprofil
Anmeldungsdatum: 17.08.2005
Beiträge: 37
|
Zebald Mitglied
01:54:49 07.12.2011 Titel: |
|
Zitieren |
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? |
Zuletzt bearbeitet von Zebald am 01:55:42 07.12.2011, insgesamt 1-mal bearbeitet |
|
 |
ihhDonkey
Unregistrierter
|
ihhDonkey Unregistrierter
11:55:12 07.12.2011 Titel: |
|
Zitieren |
| 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? |
|
|
|
 |
Zebald
Mitglied
Benutzerprofil
Anmeldungsdatum: 17.08.2005
Beiträge: 37
|
Zebald Mitglied
21:41:06 09.12.2011 Titel: |
|
Zitieren |
| 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. |
|
|
|
 |
ihhDonkey
Unregistrierter
|
ihhDonkey Unregistrierter
23:43:15 11.12.2011 Titel: |
|
Zitieren |
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? |
|
|
|
 |
Wutz
Mitglied
Benutzerprofil
Anmeldungsdatum: 15.04.2010
Beiträge: 2103
|
Wutz Mitglied
13:25:57 13.12.2011 Titel: |
|
Zitieren |
| Code: | | select fID from tG where gID in(7,18,26) group by fID having count(*)=3 | |
| Code: | | select fID from tG where gID in(7,18,26) group by fID having count(*)=3 | |
| Code: | | select fID from tG where gID in(7,18,26) group by fID having count(*)=3 | |
|
_________________ Java, the best argument for Smalltalk since C++. -- Frank Winkler
|
|
 |
Zebald
Mitglied
Benutzerprofil
Anmeldungsdatum: 17.08.2005
Beiträge: 37
|
Zebald Mitglied
21:30:56 14.12.2011 Titel: |
|
Zitieren |
| 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.
| Code: | 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;
| |
| Code: | 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;
| |
| Code: | 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) |
|
|
|
 |