Hallo,
wir haben eine Datenbank mit zwei Tabellen:
Objekte (Felder: Objekt_ID, ...) und
Index (Felder: Objekt_ID, Indextyp, Indextext, ...), verbunden über die Objekt_ID.
Mit jedem Datensatz in Objekte sollen folgende Datensätze in Index verbunden sein:
Indextyp "S": genau ein Datensatz,
Indextyp "P": kein Datensatz bis mehrere Datensätze,
Indextyp "O": kein Datensatz bis mehrere Datensätze.
Zu jedem Objekt muss also genau ein "S"-Index vorhanden sein, während das für die anderen Indextypen egal ist.
Wenn ich die beiden Tabellen in einer Abfrage mit JOIN verbinde, kann ich prüfen, welche Datensätze wie miteinander verbunden sind.
Was aber mache ich, wenn ich herausfinden will, welche Datensätze aus Objekte (entgegen der Vorgabe) KEINEN ENTSPRECHENDEN DATENSATZ vom Typ "S" in Index haben ?
Wahrscheinlich ist die Antwort ganz einfach, aber ich stehe auf dem Schlauch. Kann mir jemand runterhelfen ?
Hallo,
vermutlich suchst Du dies: http://www.donkarl.com/?FAQ3.16
Das SQL-Statement von donkarl sieht vielversprechend aus:
SELECT A.*
FROM A LEFT JOIN B ON A.Id = B.Id
WHERE B.Id Is Null
Ich habe es ausprobiert und für ein bestimmtes Objekt den zugehörigen Indextyp von "S" in "X" verfälscht.
Allerdings wird dieses Objekt durch die Abfrage nicht gezeigt - ich vermute, weil ihm noch ein weiterer Index (vom Typ "P") zugeordnet ist.
Kann man die Abfrage so erweitern, dass sie das Fehlen von Indextyp "S" auch dann anzeigt, wenn dem Objekt noch andere Indextypen (ungleich "S") zugeordnet sind ?
Oder ist diese Lösung nur für Fälle geeignet, wo gar keine Entsprechung in der anderen Tabelle existiert ?
Hallo,
zeige mal den Screenshot des Beziehungsfensters mit allen Tabellen und -feldern und mach ein aussagekräftiges Beispiel
Ich habe mal das Beziehungsfenster und die Test-Datenbank mit der Minimalkonfiguration für diese Fragestellung beigefügt.
Objekt 1 ist ein "S"-Index und ein paar andere Indexe zugeordnet - das ist der Normalfall.
Objekt 2 ist nur ein "S"-Index zugeordnet - das ist der Minimalfall.
Objekt 3 sind ein paar Indexe, aber kein "S"-Index zugeordnet - das ist regelwidrig.
Objekt 4 ist kein Index zugeordnet - das ist erst recht regelwidrig.
Die Abfrage gemäß donkarl
SELECT Objekte.*, Index.*
FROM Objekte LEFT JOIN [Index]
ON Objekte.Objekt_ID = Index.Objekt_ID
WHERE Index.ID Is Null;
findet Objekt 4, weil dem gar kein Index zugeordnet ist,
ohne die "where"-Klausel werden die Objekte 1 bis 3 gefunden, weil sie irgendwelche Zuordnungen haben.
Wie finde ich das Objekt (2) Korrektur: Objekt (3), dem zwar ein paar Indexe zugeordnet sind, nicht aber der obligatorische Indextyp "S" ?
Hallo,
vielleicht so:
SELECT * from objekte As O where not Exists
(Select I.objekt_id from Index as I where I.Indextyp = "S" and O.objekt_id = I.objekt_id group by I.Objekt_ID )
Oder so:
SELECT
O.*
FROM
Objekte AS O
LEFT JOIN
(
SELECT
Objekt_ID
FROM
[Index]
WHERE
Indextyp = "S"
) AS I
ON O.Objekt_ID = I.Objekt_ID
WHERE
I.Objekt_ID IS NULL
(erst filtern, dann Fehlmenge per Inkonsistenzabfrage ermitteln)
Danke für die Rückmeldungen !
Beide Ansätze funktionieren (auch ohne das " group by I.Objekt_ID" von DF6GL's Ansatz).
Mir scheint, dass der Lösungsansatz von donkarl den Sonderfall einer allgemeineren Fragestellung abdeckt, die man so formulieren könnte:
http://www.donkarl.com?FAQ3.16, verallgemeinert:
Problem:
Du hast 2 Tabellen "A" und "B" (verbunden über A.ID und B.A_ID) und möchtest herausfinden,
a) (Allgemeiner Fall)
...welche Datensätze sich in A befinden, bei denen die verbundenen Datensätze in B bestimmte Bedingungen NICHT erfüllen.
b) (Spezialfall)
...welche Datensätze sich in A befinden, bei denen verbundene Datensätze in B NICHT existieren.
Lösung:
Angenommen, die oben geforderte Bedingung sei: B.Kriterium = "S":
Das SQL-Statement sieht dann ca. so aus:
SELECT * FROM A
WHERE not Exists
(Select B.A_ID from B
where
B.Kriterium = "S" and
A.ID = B.A_ID);
Für den Spezialfall lässt man die Zeile "B.Kriterium = "S" and" einfach weg.