April 18, 2021, 02:39:16

Neuigkeiten:

Wenn ihr euch für eine gute Antwort bedanken möchtet, im entsprechenden Posting einfach den Knopf "sag Danke" drücken!


History in Tabelle speichern und mit Abfrage nach aktuellsten Eintrag filtern

Begonnen von Dimivo, März 11, 2021, 20:57:14

⏪ vorheriges - nächstes ⏩

Dimivo

Hallo zusammen

ich möchte eine Datenbank zur Verwaltung von Artikeln erstellen. Diese Artikel haben Mengenabhängige Preise und ändern sich von Zeit zu zeit.

Ich habe 2 Tabellen, 1x Artikel-Stammdaten und 1x Preishistory mit Staffelung (Staffelung ist bei jedem Artikel unterschiedlich).

Mit der ersten Abfrage filtere ich heraus, welches Datum pro Artikel die aktuellsten Preise hat. Dies funktioniert problemlos. In meiner Beispieldatenbank sind dies 20 Artikel bei einer History von 61 Einträgen.

Mit der zweiten Abfrage möchte ich die 20 Artikel aus der Abfrage mit den 20 Artikeln in der Tabelle Preishistory verbinden, so dass ich jeweils den aktuellsten Preis sehe. Es werden bei mir jedoch 21 Artikel angezeigt anstatt 20.

Im Anhang habe ich eine Musterdatenbank hochgeladen, wie ich es aktuell aufgebaut habe. In der Abfrage qry_aktuelle_Preise ist ersichtlich, dass Artikel 17 zwei mal erscheint mit unterschiedlichem Datum.

Worin liegt der Fehler bei meinem Ansatz?

Gruss
Dimivo

ebs17

qry_Vorfilter ist der richtige Anfang. Damit wird pro Fremdschlüssel des höchste Preisdatum ermittelt.
In der zweiten Abfrage verknüpfst Du aber nur über das Datum. Da können sich bezüglich der zugeordneten Fremdschlüssel und dann auch Preise ganz wilde und vor allem auch falsche Ergebnisse ergeben. Die Massengruppierung ist dann auch nur ein verzweifelter Versuch, da herauszukommen.

Gehe so vor:
SELECT
   MAX(FOB_Datum) AS MaxDatum,
   FOB_Artikel_Ref_ID
FROM
   tbl_Artikel_Preise_History
GROUP BY
   FOB_Artikel_Ref_ID
Das ist Deine erste Abfrage, leserlich zusammengekürzt.
Diese Abfrage muss nun mit der Tabelle erneut verknüpft werden, um pro Fremdschlüssel-Datums-Kombination die zugehörigen Inhalte der anderen Felder zu bekommen:
SELECT
   P.*
FROM
   tbl_Artikel_Preise_History AS P
      INNER JOIN
         (
            SELECT
               MAX(FOB_Datum) AS MaxDatum,
               FOB_Artikel_Ref_ID
            FROM
               tbl_Artikel_Preise_History
            GROUP BY
               FOB_Artikel_Ref_ID
         ) AS MD
         ON P.FOB_Artikel_Ref_ID = MD.FOB_Artikel_Ref_ID
            AND
         P.FOB_Datum = MD.MaxDatum
Diese Abfrage wäre nun noch mit der Artikeltabelle zu verknüpfen, um die Klarnamen für die Artikel zu bekommen.

Sowie: Entferne das Nachschlagefeld beim Fremdschlüssel. Ein Feld sollte immer das anzeigen was drin steht, sonst wird man verrückt, wenn man sich Zusammenhänge erschließen will.
Mit freundlichem Glück Auf!

Eberhard

Dimivo

Hallo Eberhard,

dank deinem Beispiel sehe ich nun, worin der Fehler lag. Vielen Dank für deine rasche Unterstützung.

Gruss
Michael

ebs17

Ein kleiner Zusatz: Damit sie das Gleiche im Ergebnis tun, kann man Abfragen aber durchaus sehr unterschiedlich formulieren.

Die obige Variante dürfte die schnellste sein, ist aber nicht aktualisierbar - was für eine Nur-Anzeige auch völlig in Ordnung ist. Die folgende Variante ist dann aktualisierbar, hat aber wegen der korrelierenden Unterabfrage, also systematisch bedingt, einige Performancenachteile. Spürbare Nachteile wird man dann bei größeren Datenmengen feststellen.
SELECT
   P.*
FROM
   tbl_Artikel_Preise_History AS P
WHERE
   P.FOB_Datum IN
      (
         SELECT TOP 1
            U.FOB_Datum
         FROM
            tbl_Artikel_Preise_History AS U
         WHERE
            U.FOB_Artikel_Ref_ID = U.FOB_Artikel_Ref_ID
         ORDER BY
            U.FOB_Datum DESC
      )
Mit freundlichem Glück Auf!

Eberhard