Supportnet / Forum / Datenbanken
Kleines Abfrage Problem
Frage
Ich habe in meiner Datenbank folgende Abfrage
SELECT Adressen.Firma, Adressen.Abteilung, Adressen.Stadt, Adressen.Straße, Adressen.ID
FROM Adressen, [Kopie von Adressensuchen], [Kopie von Name->FirmenID]
WHERE (((Adressen.ID)=[Kopie von Name->FirmenID]![ID] Or (Adressen.ID)=[Adressensuchen]![ID]))
GROUP BY Adressen.Firma, Adressen.Abteilung, Adressen.Stadt, Adressen.Straße, Adressen.ID;
Das ganze ist teil einer Volltextsuche in einer Adresssammlung, die aus 2 Tabellen besteht, in der 1. stehen die Adressen und Firmennamen, in der 2. sind den Firmen verschiedene Ansprechpartner zugeordnet. Die beiden Abfragen Name->FirmenID und
Adressensuchen liefern nun jeweils die ID´s aller Einträge zurück die den Suchkriterien entsprechen, diese Abfrage soll nun den ID´s zugeornete Firmen ausgeben, dies tut sie aber nur wenn beide Abfragen Ergebnisse liefern, wenn eine von beiden nichts findet bleibt auch das Gesamtergebnis leer. Warum ist das so?
Antwort 1 von Flooooo
Zitat:
dies tut sie aber nur wenn beide Abfragen Ergebnisse liefern
dies tut sie aber nur wenn beide Abfragen Ergebnisse liefern
Das hat ein Join so an sich :-) - denn eine Bedingung ist ja, dass nur Tupel selektiert werden, die die "Gleichheitsbedingung" (id) erfüllen. Sprich: Wenn du einer Firma keinen Ansprechpartner zugeordnet hast, dann kommt dazu natürlich kein Datensatz raus, weil kein Tupel gefunden wird, bei denen die beiden Ansprechpartner-IDs gleich sind.
Antwort 2 von Woodman
Ja das ich keine Datensatz kriege wenn nicht gefunden wird is mir klar, aber wenn Name->FirmenID ein Ergebnis liefert, Adressensuchen aber nichts findet (seltener Name gesucht) bleibt das Ergebnis diese Abfrage leer, sobald beide Abfragen etwas finden werden alle Ergebnisse korrekt ausgegeben, was muss ich denn ändern damit ich die einzel Ergebnisse auch zu sehen bekomme? Für mich macht das irgendwie grad keinen Sinn, da steht doch ODER, also ist die Bedingung doch wahr wenn mindestens Eine ID passt oder nicht?
Antwort 3 von Flooooo
Kannst du vielleicht mal die Tabellenstrukturen posten, damit man sich nochmal ein genaues Bild machen kann, was in welcher Tabelle steht?
Antwort 4 von Woodman
Also
in Adressen
Firma, Abteilung, straße .... und ID als eindeutiger index
in Ansprechpartner
vorname, Nachname ... und die ID der zugehörigen Firma
Name->FirmenID durchsucht Ansprechpartner und gibt nur die ID´s zurück
Adressensuchen durchsucht Adressen und gibt auch die ID´s zurück
Die Abfrage soll jetz die ID´s der beiden Abfragen nehmen und Firmenname und so weiter ausgeben
in Adressen
Firma, Abteilung, straße .... und ID als eindeutiger index
in Ansprechpartner
vorname, Nachname ... und die ID der zugehörigen Firma
Name->FirmenID durchsucht Ansprechpartner und gibt nur die ID´s zurück
Adressensuchen durchsucht Adressen und gibt auch die ID´s zurück
Die Abfrage soll jetz die ID´s der beiden Abfragen nehmen und Firmenname und so weiter ausgeben
Antwort 5 von Flooooo
Eben - was ist die Struktur von Adressensuchen?
Antwort 6 von Flooooo
So, ich hab glaub ich grob verstanden, was du willst. Punkt1: Das ist wieder so Access-Geschreddel, sorry, ich bin eher "SQL-Mensch" :-)
Prinzipiell würde die Abfrage in etwas so aussehen: (in etwa, weil ja adressensuchen und Name eigentlich SELECTS sind, die man in SQL auch hinschreiben wsürde; wie genau das in Access interpretiert werden kann - kA:
Prinzipiell würde die Abfrage in etwas so aussehen: (in etwa, weil ja adressensuchen und Name eigentlich SELECTS sind, die man in SQL auch hinschreiben wsürde; wie genau das in Access interpretiert werden kann - kA:
SELECT DISTINCT Adressen.Firma, Adressen.Abteilung, Adressen.Stadt, Adressen.Straße, Adressen.ID
FROM Adressen, Ansprechpartner, Adressensuchen, Name
WHERE
Adressen.FirmenID IN (Adressensuchen.FirmenID
UNION
Name.FirmenID)
AND
Adressen.FirmenID = Ansprechpartner.FirmenID;
Antwort 7 von Woodman
Ja Danke, für meinen Bedarf muss die AND Bedingung am Ende weg, aber Access mag den Ausdruck nich, habs jetz völlig unelgant gelöst indem ich die beiden Abfragen verschachtelt hab.
Antwort 8 von Flooooo
Wenn du aber die AND-Bed. weglässt, bekommst du ein Kreuprodukt! (Alle in der Suche enthaltenen FirmenIDs * Alle Ansprechpartner)
Antwort 9 von Woodman
Hab ich die UNION Anweisung ketz falsch verstanden? Ich dachte die würde aus den beiden Ergebnistabellen eine einzelne machen
Antwort 10 von Flooooo
@Woodman:
Ne, die Union hast du richtig verstanden, aber es passiert doch folgendes:
Schritt 0: Wir haben eine Tabelle "Adressen", die alle Adressen enthält, eine Tabelle "Ansprechpartner", die sämtliche bekannten Ansprechpartner (aller Firmen) enthält.
Dazu 2 Abfragen Adressensuchen und Name, die FirmenIDs enthalten, auf die die Suche zutraf. Ich gehe davon aus, dass "Adressensuchen" in den Adressen sucht und "Name" in der Ansprechpartner-Tabelle. (ist übrigens eigentlich ungeschickt, mehr dazu unten)
Schritt 1: (Adressensuchen.FirmenID UNION Name.FirmenID) fasst die beiden Suchergebnisse zusammen - d.h. hier entsteht eine Liste, die alle FirmenIDs enthält, auf die die Suche (gleich ob Name oder Adresse) zutrifft.
Schritt 2: Adressen.FirmenID IN Adressensuchen.FirmenID UNION Name.FirmenID) heißt nun in Prosa: Selektiere nur die Datensätze aus Adressen, die eine FirmenID besitzen, die in der Liste (Schritt 1) vorkommt.
Schritt 3: Würde man hier aufhören, so würde ja noch ein Kreuzprodukt auf Adressen & Ansprechpartner gebildet, d.h. jeder Firma aus der (eingeschränkten) Liste würde jeder Ansprechpartner zugeordnet, klar soweit? Deshalb noch die zweite Einschränkung AND Adressen.FirmenID = Ansprechpartner.FirmenID;
So, jetzt aber noch was anderes: Wieso teilst du dein Suchergebnis eigentlich vorher auf 2 Abfragen auf?
Besser wäre doch folgendes:
Eine Abfrage SELECT * FROM Adressen, Ansprechpartner WHERE Adressen.FirmenID = Ansprechpartner.FirmenID;
So, das liefert jetzt also eine Liste die jeweils Firma und Ansprechpartner als einen Datensatz enthält.
Und jetzt lass doch deine Suche am besten darauf los, und zwar auf "alle" Felder (z.B. Namen und Adressen) - die Einschränkung bekommst du dann ja direkt.
Ne, die Union hast du richtig verstanden, aber es passiert doch folgendes:
Schritt 0: Wir haben eine Tabelle "Adressen", die alle Adressen enthält, eine Tabelle "Ansprechpartner", die sämtliche bekannten Ansprechpartner (aller Firmen) enthält.
Dazu 2 Abfragen Adressensuchen und Name, die FirmenIDs enthalten, auf die die Suche zutraf. Ich gehe davon aus, dass "Adressensuchen" in den Adressen sucht und "Name" in der Ansprechpartner-Tabelle. (ist übrigens eigentlich ungeschickt, mehr dazu unten)
Schritt 1: (Adressensuchen.FirmenID UNION Name.FirmenID) fasst die beiden Suchergebnisse zusammen - d.h. hier entsteht eine Liste, die alle FirmenIDs enthält, auf die die Suche (gleich ob Name oder Adresse) zutrifft.
Schritt 2: Adressen.FirmenID IN Adressensuchen.FirmenID UNION Name.FirmenID) heißt nun in Prosa: Selektiere nur die Datensätze aus Adressen, die eine FirmenID besitzen, die in der Liste (Schritt 1) vorkommt.
Schritt 3: Würde man hier aufhören, so würde ja noch ein Kreuzprodukt auf Adressen & Ansprechpartner gebildet, d.h. jeder Firma aus der (eingeschränkten) Liste würde jeder Ansprechpartner zugeordnet, klar soweit? Deshalb noch die zweite Einschränkung AND Adressen.FirmenID = Ansprechpartner.FirmenID;
So, jetzt aber noch was anderes: Wieso teilst du dein Suchergebnis eigentlich vorher auf 2 Abfragen auf?
Besser wäre doch folgendes:
Eine Abfrage SELECT * FROM Adressen, Ansprechpartner WHERE Adressen.FirmenID = Ansprechpartner.FirmenID;
So, das liefert jetzt also eine Liste die jeweils Firma und Ansprechpartner als einen Datensatz enthält.
Und jetzt lass doch deine Suche am besten darauf los, und zwar auf "alle" Felder (z.B. Namen und Adressen) - die Einschränkung bekommst du dann ja direkt.
Antwort 11 von Woodman
Danke das klingt in der Tat einfacher als das logik chaos das ich grade benutze.
Aber wenn ich das richtig verstehe hab ich ein Problem, es kann in der Datenbank durchaus vorkommen das einer Firma kein Ansprechpartner zugeordnet ist, fallen diese Datensätze dann nicht raus?
Aber wenn ich das richtig verstehe hab ich ein Problem, es kann in der Datenbank durchaus vorkommen das einer Firma kein Ansprechpartner zugeordnet ist, fallen diese Datensätze dann nicht raus?
Antwort 12 von Floooooo
Das stimmt, dann fallen sie raus.
Die schnellste Lösung wäre ein "Phantomansprechpartner", also z.B. der Partner mit der ID = 0 und dem Namen "Kein Ansprechpartner vorhanden" oder irgendsowas - die Beziehung zwischen den Tabellen muss dann referentielle Integrität besitzen, d.h. jeder Firma muss mind. 1 Anspreechpartner zugeordnet werden.
Die schnellste Lösung wäre ein "Phantomansprechpartner", also z.B. der Partner mit der ID = 0 und dem Namen "Kein Ansprechpartner vorhanden" oder irgendsowas - die Beziehung zwischen den Tabellen muss dann referentielle Integrität besitzen, d.h. jeder Firma muss mind. 1 Anspreechpartner zugeordnet werden.
Antwort 13 von Floooooo
PS:
Ich persönlich finde die eben beschriebene Lösung (AW12) schöner, falls du das aber nicht so benuztzen möchtest, sondern wie bisher, wie wäre es dann einfach mit
Dann werden alle Firmen mit Ansprechpoartner selektiert und alle Firmen ohne Ansprechpartner.
Ich persönlich finde die eben beschriebene Lösung (AW12) schöner, falls du das aber nicht so benuztzen möchtest, sondern wie bisher, wie wäre es dann einfach mit
SELECT * FROM Adressen, Ansprechpartner
WHERE
Adressen.FirmenID = Ansprechpartner.FirmenID
OR
Adressen.FirmenID NOT IN
(SELECT FirmenID FROM Ansprechpartner);
Dann werden alle Firmen mit Ansprechpoartner selektiert und alle Firmen ohne Ansprechpartner.
Antwort 14 von Floooooo
Ups, Kommando zurück: Eigentlich darfv die eben genannte Abfrage nicht laufen, weil ja dann u.U. keine "Ansprchpartnerfelder" vorhanden sind...

