Neuigkeiten:

Ist euer Problem gelöst, dann bitte den Knopf "Thema gelöst" drücken!

Mobiles Hauptmenü

Problem mit Datumskriterium in Abfrage

Begonnen von Paule, September 24, 2016, 07:48:17

⏪ vorheriges - nächstes ⏩

Paule

Hallo,
ich habe folgendes Problem:
Ich habe eine Tabelle CF_InstallmentsT in der alle Raten gespeichert sind. Die Felder sind:
InstallmentID
ReferingSale (hier eigentlich die SalesID -> schlechte Benennung, ich weiß)
InstallmentDate (Datum)
InstallmentSum (Raten-Umfang)
Notes (Kommentare)

Nun möchte ich mir in einer Abfrage für ein Listenfeld nur ausgewählte Installments eines Kunden anzeigen lassen.
Fall A) Ich möchte alle Installments sehen
Fall B) Ich möchte alle Installments sehen, die vor dem Rücknahme-Zeitpunkt angefallen sind.

In der Tabelle SA_Retakes werden alle Rücknahmen aufgeführt. Folgende Felder gibt es:
RetakeID
RetakeDate
CustomerID
SalesID
SerialNo
RetakeType
RetakeItem

Beide Tabellen habe ich für die Abfrage über SalesID bzw. ReferingSale verknüpft.

In der Abfrage möchte ich mir soweit anzeigen lassen:
-InstallmentID
-ReferingSale
-InstallmentDate
-InstallmentSum
-Notes

Für das Datumskriterium möchte ich wie oben beschrieben beide Fälle abgedeckt haben. Daher hatte ich eine If-Anweisung als Kriterium verwendet:
Wenn([SA_Retakes].[RetakeID] Ist Null,("*"),<[SA_Retakes].[RetakeDate])

Wenn ich das tue, zeigt er mir allerdings bei einem exemplarischen Kunden, dessen Produkt nicht zurückgenommen wurde (RetakeID Ist Null), keine Raten mehr an, obwohl da welche sein sollten, weil er ja im Fall das es kein Retake bisher gibt, alle Installments anzeigen soll.

Was mache ich falsch?
Anbei auch noch ein Screenshot.

Ich wäre euch sehr dankbar für eine Hilf.

Viele Grüße

Lachtaube

Ich denke, dass die Verknüpfung über einen Left Join eher erfolgreich wird.SELECT r.*, i.*
  FROM SA_Retakes r
  LEFT JOIN CF_InstallmentsT i
         ON r.SalesID = i.ReferingSale
WHERE i.InstallmentDate < r.RetakeDate
       OR
       r.RetakeDate Is Null;
Mit dem anderen Parameter kann ich nichts anfangen.

PS: statt des Screenshots wäre ein gezipptes Beispiel Deiner DB (idealerweise als mdb vorlieged) aussagekräftiger.
Grüße von der (⌒▽⌒)

Paule

Hallo Lachtaube,
danke für die Hinweise. Einen Left Join hatte ich schon.
Mit deinem Code werden diesmal sogar Datensätze angezeigt. Also geht es schon mal in die richtige Richtung. :)
Aber so richtig klappen tut es noch nicht.
Anbei mal die Datenbank.
Es geht um das Formular SA_DeleteInstallments.
Mein Testdatensatz ist SalesID 386. Bei diesem Sale gab es 9 Installments. Mittlerweile habe ich nur noch Rate 1, Rate 5, Rate 6, Rate 7, Rate 8 und Rate 9 in der Tabelle CF_Installments.
Eine RÜcknahme ist angelegt am 24.4.2017. Das bedeutet, er sollte mir nur noch alle Raten ab diesem Zeitpunkt anzeigen. Rate 8 und Rate 9 dürften nicht angezeigt werden, da diese nach dem 24.4. 2017 liegen.
(Gleichzeitig aber auch alle Raten, wenn keine RÜcknahme angelegt wäre).

So richtig bekomme ich das noch nicht hin... :(

Für Hilfe wäre ich sehr dankbar!

Lachtaube

Nun, das Datumskriterium sollte doch stimmen. Wo ist das Problem?

BTW: das Riesen-Beispiel kann ich mir mit meiner Access-Version zu Hause nicht ansehen.
Grüße von der (⌒▽⌒)

Paule

Hallo Lachtaube,
ich habe das Ganze jetzt mit einem Right Join gelöst.

SELECT CF_InstallmentsT.InstallmentID, CF_InstallmentsT.ReferingSale, CF_InstallmentsT.InstallmentDate, CF_InstallmentsT.InstallmentSum, CF_InstallmentsT.Notes
FROM SA_Retakes RIGHT JOIN CF_InstallmentsT ON SA_Retakes.SalesID = CF_InstallmentsT.ReferingSale
WHERE (((CF_InstallmentsT.InstallmentDate)<[SA_Retakes].[RetakeDate])) Or SA_Retakes.RetakeDate Is Null;


So passt es jetzt.

Vielen, vielen Dank für die Hinweise!

Paule

Ich habe das Ganze jetzt noch einmal "lebend" probiert. In der Test-Variante hatte es gut funktioniert, jetzt allerdings nicht mehr.

Ich möchte wieder oben genannte beide Fälle umsetzen:
- A) Alle Raten/Installments von Verkäufen, die NICHT zurückgenommen wurden
- B) Alle Raten/Installments, die vor dem Rücknahmedatum anfielen, sofern das Produkt zurückgenommen wurde.

Dies wollte ich so erreichen:
SELECT CF_InstallmentsT.InstallmentID, CF_InstallmentsT.InstallmentDate, CF_InstallmentRepayment.RepaymentDate, CF_InstallmentRepayment.RepaymentAmount, SA_Retakes.RetakeDate
FROM (CF_InstallmentsT INNER JOIN CF_InstallmentRepayment ON CF_InstallmentsT.InstallmentID = CF_InstallmentRepayment.InstallmentNo) LEFT JOIN SA_Retakes ON CF_InstallmentsT.ReferingSale = SA_Retakes.SalesID
WHERE (((CF_InstallmentsT.InstallmentDate)<[SA_Retakes].[RetakeDate])) OR (((SA_Retakes.RetakeDate) Is Null));

Hat aber leider nicht funktioniert. Die Datensätze, die er anzeigt, sind viel zu wenig. Wenigstens gibt es keine Fehlermeldung...

Lachtaube

Access macht i.d.R. das mit den Daten, was in SQL angewiesen wird. Wenn ohne Inner Join die richtigen Daten erscheinen, muss Du diesen auch noch in einen Outer Join umwandeln.

BTW: ein Retake ist übrigens eine Wiederholung. :)
Grüße von der (⌒▽⌒)

Paule

Ich habe jetzt folgendes probiert:
SELECT CF_InstallmentsT.InstallmentID, CF_InstallmentsT.InstallmentDate, CF_InstallmentRepayment.RepaymentDate, CF_InstallmentRepayment.RepaymentAmount, SA_Retakes.RetakeDate
FROM (CF_InstallmentsT LEFT OUTER JOIN SA_Retakes ON CF_InstallmentsT.ReferingSale = SA_Retakes.SalesID) INNER JOIN CF_InstallmentRepayment ON CF_InstallmentsT.InstallmentID = CF_InstallmentRepayment.InstallmentNo
WHERE (((CF_InstallmentsT.InstallmentDate)<[SA_Retakes].[RetakeDate])) OR (((SA_Retakes.RetakeDate) Is Null));


Leider keine Veränderung. Ich kenne mich mit Outer Joins leider nicht wirklich aus. Soweit ich das verstanden habe, sage ich damit lediglich, dass er mir alle Datensätze anzeigen soll, die eine bestimmte Bedingung erfüllen und darüber hinaus alle Datensätze einer der Tabellen, die über den Outer Join verknüpft sind.

Welche Tabelle müsste ich dann wie mit dem Outer Join verknüpfen?
Mein Ziel ist es doch, dass alle Datensätze aus CF_InstallmentsT angezeigt werden, die die Bedingung erfüllen, dass da CF_InstallmentT.InstallmentDate < SA_Retakes.RetakeDate ist und sonst alle Datensätze aus CF_InstallmentsT.
Das heißt, der erste Teil müsste doch stimmen? Allerdings werden mir immer noch nicht genügend Datensätze angezeigt. Ist an dem zweiten Inner Join etwas falsch?

Lachtaube

Left- und Right-Joins sind Outer Joins. Bei einem Inner Join werden nur die Daten angezeigt, die in der Verknüpfung auf beiden Seiten vorkommen. Bei einem Outer Join werden zusätzlich auch die Daten der linken bzw. der rechten Seite angezeigt, die kein Pendant in der verknüpften haben.

Das sind Grundlagen für das sinnvolle Arbeiten mit Access, die auch leicht zu erlernen sind.
SELECT i.InstallmentID,
       i.InstallmentDate,
       r.RepaymentDate,
       r.RepaymentAmount,
       s.RetakeDate
  FROM (CF_InstallmentsT AS i
         LEFT JOIN SA_Retakes AS s
                ON i.ReferingSale = s.SalesID)
       LEFT JOIN CF_InstallmentRepayment AS r
              ON i.InstallmentID = r.InstallmentNo
WHERE i.InstallmentDate < s.RetakeDate
       OR
       s.RetakeDate Is Null;

PS: Beim Posten von SQL-Abfragen bitte vorher in einem Editor sinnvoll Zeilenumbrüche setzen - sonst kann den Code kein Mensch lesen.
Grüße von der (⌒▽⌒)