Neuigkeiten:

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

Mobiles Hauptmenü

Identische Datensätze aber unterschiedliche Ergebnisse

Begonnen von sellrich, Februar 07, 2019, 11:03:19

⏪ vorheriges - nächstes ⏩

sellrich

Hallo zusammen,

ich habe einige Zeit versucht eine Beispieldatenbank zu erstellen, um euch mein Problem simpel erklären zu können. Leider wurde diese Datenbank von meinem "Vorgänger" so verwirrend und kompliziert erstellt, dass ich es nicht hinkriege. Mein Wissen in Access und VBA sind leider nicht so umfangreich.

Komme ich mal zum Thema.

Es existiert eine Tabelle (Kundenumsatz) mit Inhalten die sich auf Umsatzdaten beziehen.
Diese Tabelle wird nächtlich aus unserer WaWi aktualisiert. Soweit so gut - funktioniert einwandfrei.
Falls es hilft könnte ich die Struktur der Tabelle hochladen.

Jetzt habe ich den Auftrag bekommen diese Tabelle 1 zu 1 auf unseren SQL Server zu kopieren. Bis dato auch simpel - einfach eine Aktualisierungsabfrage die die Felder 1 zu 1 rüber kopiert. Bei 2 Millionen Datensätzen dauert das eine Weile. Aufgrund des PK´s gibt es auch keine doppelten Datensätze. Es wird nur kopiert was in der "neuen SQL" Tabelle bisher nicht existiert - wie es sein soll.

Jetzt mein Problem :
Ist die neue SQL Tabelle leer und ich führe die Abfrage aus - klappt es. Die Datensätze sind identisch und meine Abfrage führt auch zu dem identischen Umsatzergebnis wie mit der aktuellen "alten" Tabelle.

Aktualisiert sich die Tabelle nachts mit den fehlenden bzw. neu hinzugekommenen Datensätzen haben beide Tabellen identische Datensätze. Meine Abfrage jedoch "realisiert" das irgendwie nicht. Ich kriege als Ergebnis einen ganz anderen Umsatz angezeigt.

Bevor ich wahllos irgendwelche weiteren Infos wie Code oder so rein poste - welche Infos werden noch benötigt?

PhilS

Zitat von: sellrich am Februar 07, 2019, 11:03:19
Aktualisiert sich die Tabelle nachts mit den fehlenden bzw. neu hinzugekommenen Datensätzen haben beide Tabellen identische Datensätze. Meine Abfrage jedoch "realisiert" das irgendwie nicht. Ich kriege als Ergebnis einen ganz anderen Umsatz angezeigt.
Das ergibt nicht wirklich Sinn!
Ich würde erstmal versuchen das auf eine ganz kleine Datenmenge (z.B. nur 1 Tag) einzugrenzen bei der sich reproduzierbar diese Differenzen zwischen den beiden Abfragen reproduzieren lassen. Evtl. lassen sich dann anhand des Fehlbetrages schon einzelne Datensätze identifizieren, die nur ein einer Abfrage berücksichtigt werden.
Was du hier posten könntest, wären die SQL-Statements der beiden Abfragen. Vielleicht lässt sich daran schon etwas erkennen.
Neue Videoserie: Windows API in VBA

Klassische CommandBars visuell bearbeiten: Access DevTools CommandBar Editor

sellrich

ZitatIch würde erstmal versuchen das auf eine ganz kleine Datenmenge (z.B. nur 1 Tag) einzugrenzen
Alles klar. Habe jetzt die neue Liste manuell geleert und mit der Abfrage befüllen lassen. Werte sind identisch. Dann kann ich dazu erst morgen berichten. Da neue Daten erst wieder über Nacht generiert werden. Dann haben wir aber einen Unterschied von einem Tag. Da aber Datensätze von der Anzahl her identisch sind weiß ich nicht wie das helfen soll? Mach es aber trotzdem gerne.

ZitatWas du hier posten könntest, wären die SQL-Statements der beiden Abfragen. Vielleicht lässt sich daran schon etwas erkennen.

Die Abfrage um den Umsatz zu ermitteln, sowie die Abfrage fürs Tabellen kopieren? Gerne!

Abfrage auf "alte" Tabelle
SELECT Sum(Kundenumsatz.netto) AS Summevonnetto
FROM Kundenumsatz
WHERE (((Kundenumsatz.Jahr)=2019) AND ((Kundenumsatz.Monat)=1));

Abfrage auf SQL "neue" Tabelle
SELECT Sum(dbo_KUNDENUMSATZ.netto) AS Summevonnetto
FROM dbo_KUNDENUMSATZ
WHERE (((dbo_KUNDENUMSATZ.Jahr)=2019) AND ((dbo_KUNDENUMSATZ.Monat)=1));


btw: Ich habe die Tabellennamen hier unterschiedlich benannt zur leichteren Identifikation. Im normalen Ablauf heißen diese identisch.

Hier die Aktualisierungsabfrage :
INSERT INTO dbo_KUNDENUMSATZ ( SATZ, Monat, Jahr, liefnr, knr, remf, vnr1, vnr2, wgnr, artnr, menge, slbk, vkp, netto, brutto, mwst, BONUS, Prüfsumme )
SELECT Kundenumsatz.SATZ, Kundenumsatz.Monat, Kundenumsatz.Jahr, Kundenumsatz.liefnr, Kundenumsatz.knr, Kundenumsatz.remf, Kundenumsatz.vnr1, Kundenumsatz.vnr2, Kundenumsatz.wgnr, Kundenumsatz.artnr, Kundenumsatz.menge, Kundenumsatz.slbk, Kundenumsatz.vkp, Kundenumsatz.netto, Kundenumsatz.brutto, Kundenumsatz.mwst, Kundenumsatz.BONUS, Kundenumsatz.Prüfsumme
FROM Kundenumsatz LEFT JOIN dbo_KUNDENUMSATZ ON Kundenumsatz.SATZ = dbo_KUNDENUMSATZ.SATZ;


Hierbei ist die Spalte "SATZ" der Primärschlüssel, da dort nur eindeutige Werte drin vorkommen.

ebs17

ZitatHier die Aktualisierungsabfrage
Das ist eine Anfügeabfrage, denke mal nach.
Zudem hat ein einfacher LEFT JOIN nun mal gar keine Filterwirkung auf die linke Tabelle, weil per Definition alle Datensätze der linken Tabelle genommen werden.

Einige niedergelegte Gedanken: Grundlagen - SQL ist leicht (4) - Aktualisierung einer Tabelle
Bei Datenmenge hilft dann eine mögliche Indexnutzung besonders, ebenso eine frühzeitige objektive Filterung.
Mit freundlichem Glück Auf!

Eberhard

sellrich

#4
ZitatDas ist eine Anfügeabfrage, denke mal nach.
Selbstverständlich. Habe mich da vertan.

ZitatZudem hat ein einfacher LEFT JOIN nun mal gar keine Filterwirkung auf die linke Tabelle, weil per Definition alle Datensätze der linken Tabelle genommen werden.
Allerdings werden aber alle Werte die bereits vorhanden sind nicht nochmal reingeschrieben. Und nur die genommen, die es in der neuen Tabelle noch nicht gibt.

Vielleicht nochmal als Hinweis : Das das nicht die feine englische Art ist, Daten von A nach B zu bekommen weiß ich. Ich bin auch momentan dran immer mehr über das alles zu lernen, da ich eigentlich gelernter Systemintegrator bin.
An sich ist diese Konstellation nicht schön, erfüllt aber seinen (vorerst notwendigen) Zweck.
ZitatEs besteht zwar die Möglichkeit, per Anfügeabfrage alle Datensätze der Quelltabelle der Zieltabelle zuzuweisen und die Abwehr der überflüssigen Datensätze einem eindeutigen Index zu überlassen.
@ebs17 das wäre da wohl bei mir der aktuelle Fall. Versuche aber mal die Hinweise durch zu versuchen. Leider kann ich immer erst 1 Tag später feststellen, ob es was gebracht hat.

Ich wundere mich sehr darüber, dass ein komplett neues kopieren klappt. Und ein hinzufügen der neuen Datensätze (was defintiv klappt - ich vergleiche ja jeden Tag die Anzahl der DS) zwar die gleiche Menge an DS in beiden Tabellen erzeugt. Aber bei den Auswahlabfragen andere Ergebnisse erzielen. Das möchte ich gerne verstehen.

PhilS

Zitat von: sellrich am Februar 07, 2019, 13:54:32
Da aber Datensätze von der Anzahl her identisch sind weiß ich nicht wie das helfen soll?
Ich bin von einer komplexeren Abfrage ausgegangen. Wie angedeutet, wäre dann ein Ansaztpunkt gewesen, anhand des Differenzbetrages einzelne Datensätze zu identifizieren, die in der Summe fehlen.

Bei deinen Abfragen ist erstmal nichts "Verdächtiges" zu erkennen.

Wenn du die (Summen-)Abfrage mit den gleichen Kriterien als vollständige Auswahlabfrage ausführst, werden dann auch alle Datensätze angezeigt?

Kannst du "andere Ergebnisse" mal etwas etwas genauer definieren? Sind es Differenzen, die so klein sind, dass sie sich durch Rundungsfehler erklären ließen?

Was sind die Datentypen von SATZ, Netto, Jahr und Monat auf dem SQL-Server?
Neue Videoserie: Windows API in VBA

Klassische CommandBars visuell bearbeiten: Access DevTools CommandBar Editor

sellrich

ZitatWenn du die (Summen-)Abfrage mit den gleichen Kriterien als vollständige Auswahlabfrage ausführst, werden dann auch alle Datensätze angezeigt?
Ich habe das Ganze was Nachts läuft manuell angehauen. Ich kann dir dazu in circa. einer Stunde mehr sagen.

ZitatKannst du "andere Ergebnisse" mal etwas etwas genauer definieren?

Aber natürlich! Andere Ergebnisse sind nicht nachvollziehbare Differenzen. Und zwar in der SQL Tabelle (trotz gleicher Datensätze) einen Nettowert weniger 500.000€ o.ä. bei insgesamt 6.800.000 zu 6.300.000 - um mal Beispielzahlen zu haben.

ZitatWas sind die Datentypen von SATZ, Netto, Jahr und Monat auf dem SQL-Server?
In der alten Access sind es : kleiner Text, Zahl, Zahl, Zahl
SQL : nvarchar(55), float, smallint, smallint

Könnte es an "float" und "Zahl" liegen? Das es eventuell Rundungsfehler sind? Aber so massive Fehler, dass da tausende von Unterschied sind?

PhilS

Zitat von: sellrich am Februar 07, 2019, 15:07:39
ZitatWas sind die Datentypen von SATZ, Netto, Jahr und Monat auf dem SQL-Server?
In der alten Access sind es : kleiner Text, Zahl, Zahl, Zahl
SQL : nvarchar(55), float, smallint, smallint

Könnte es an "float" und "Zahl" liegen? Das es eventuell Rundungsfehler sind? Aber so massive Fehler, dass da tausende von Unterschied sind?
Einerseits würde ich jetzt davon ausgehen, dass bei dem Float-Werten das Dezimaltrennzeichen von Access nicht erkannt wird (Spracheinstellungen in der ODBC-Datenquelle, bzw des SQL-Benutzers  überprüfen!) und daher das Tausendertrennzeichen falsch interpretiert wird.


Andererseits erklärt das aber nicht, warum das Problem immer nur die Daten betrifft, die nachträglich dazugeladen werden und nicht die ursprünglichen Daten.

Ganz allgemein ist der Fließkommatyp Float kein besonders sinnvoller Datentyp für Geld-Beträge. Money ist genau dafür vorgesehen. - Das hat aber (vermutlich) nichts mit dem akuten Problem zu tun.
Neue Videoserie: Windows API in VBA

Klassische CommandBars visuell bearbeiten: Access DevTools CommandBar Editor

sellrich

Ich habe den Datentyp mal abgeändert. Da ich Montag leider erst wieder im Unternehmen bin kann ich erst Montag weitere Szenarien überprüfen.
Bis hierher schon mal vielen Dank für die Mühe. Ich melde mich Montag direkt nochmal.  :)

sellrich

#9
Hallo,

ich habe nun neue Daten. Nach Ändern des Datentyps etc. haben wir leider immer noch kein anderes Ergebnis.

Ich habe jetzt mal anhand meiner Daten Beispielzahlen.

Stand Freitag -
Die neue Tabelle dbo.Kundenumsatz mit Abfrage auf SSMS geleert. Struktur bleibt.
Abfrage in Access :

INSERT INTO dbo_KUNDENUMSATZ ( SATZ, Monat, Jahr, liefnr, knr, remf, vnr1, vnr2, wgnr, artnr, menge, slbk, vkp, netto, brutto, mwst, BONUS, Prüfsumme )
SELECT Kundenumsatz.SATZ, Kundenumsatz.Monat, Kundenumsatz.Jahr, Kundenumsatz.liefnr, Kundenumsatz.knr, Kundenumsatz.remf, Kundenumsatz.vnr1, Kundenumsatz.vnr2, Kundenumsatz.wgnr, Kundenumsatz.artnr, Kundenumsatz.menge, Kundenumsatz.slbk, Kundenumsatz.vkp, Kundenumsatz.netto, Kundenumsatz.brutto, Kundenumsatz.mwst, Kundenumsatz.BONUS, Kundenumsatz.Prüfsumme
FROM Kundenumsatz LEFT JOIN dbo_KUNDENUMSATZ ON Kundenumsatz.SATZ = dbo_KUNDENUMSATZ.SATZ;


manuell gestartet. Daten werden kopiert, Datensätze sind identisch. Bei beiden für den Monat Februar ist der Umsatz übereinstimmend.

Stand Heute -
Die alte Tabelle wird Nachts um 02:00 automatisch aus der WaWi gefüllt. Um 04:00 Uhr wird dann die oben genannte Abfrage automatisch ausgeführt und die Daten in die neue Tabelle kopiert. (eigentlich nichts anderes als ich Freitag manuell getan habe)
Eben überprüft : Datensätze im Februar sind immer noch identisch (nur höher als Freitag, es wurden ja Umsätze geschrieben)
Umsätze weisen jedoch ein Unterschied von ~71.000€ auf. Diese Differenz ist in der neuen Tabelle zu wenig.
Gesamt ~3.400.000€

PhilS

Zitat von: sellrich am Februar 11, 2019, 09:11:12
Eben überprüft : Datensätze im Februar sind immer noch identisch (nur höher als Freitag, es wurden ja Umsätze geschrieben)
Die Aussage ist mir unklar bzw. unpräzise.
Identisch heißt für mich es gib *keinen* Unterschied!
"identisch (nur höher)" ist logisch nicht möglich.

Führ doch bitte mal dein Umsatz-Abfrage direkt im SQL Server Management Studio aus. - Ist das Ergebnis dasselbe wie in Access?
Neue Videoserie: Windows API in VBA

Klassische CommandBars visuell bearbeiten: Access DevTools CommandBar Editor

ebs17

Deine genannten Differenzen ohne zugehörige Daten sind nichtssagend außer eben eine Feststellung von Dir.

Die Abfrage selber scheint Dir aber so zu gefallen, dass Du laufend die gleiche Ungeschicklichkeit wiederholst.

Wenn die Zieltabelle leer ist, kannst Du nden LEFT JOIN nicht nur vergessen, sondern besser gleich streichen. Womit sollen den die Datensätze der Quelltabelle verknüpft werden? Bitte laut beantworten.

Sollten in der Zieltabelle dann doch Daten vorliegen, führt Deine Abfragegestaltung nicht zu einer Einschränktung von Datensätzen, dafür aber zu einer Vervielfältigung der Quelldaten (überall da, wo es in der Zieltabelle den Schlüssel mehr als einmal gibt).

Ergo: Dein geschildertes Ziel und deine Abfragegestaltung haben nicht sehr viel miteinander zu tun. Darüber sollte man sich mehr wundern als über Unterschiede zwischen Erwartung und Realität.
Mit freundlichem Glück Auf!

Eberhard

PhilS

Zitat von: ebs17 am Februar 11, 2019, 09:26:43
Ergo: Dein geschildertes Ziel und deine Abfragegestaltung haben nicht sehr viel miteinander zu tun. Darüber sollte man sich mehr wundern als über Unterschiede zwischen Erwartung und Realität.
Das könnte ein Volltreffer sein!

Werden für neue Umsätze ausschließlich neue Datensätze generiert, oder werden bereits bestehende Datensätze auch aktualisiert? Wenn letzteres, solltest du dich mal mit dem Unterschied zwischen Anfüge- und Aktualisierungsabfragen auseinandersetzen!Du bezeichnest deine Abfrage zwar als Aktualisierungsabfrage, aber es ist technisch gesehen eine Anfügeabfrage.
Neue Videoserie: Windows API in VBA

Klassische CommandBars visuell bearbeiten: Access DevTools CommandBar Editor

sellrich

@PhilS
ZitatDie Aussage ist mir unklar bzw. unpräzise.
Identisch heißt für mich es gib *keinen* Unterschied!
"identisch (nur höher)" ist logisch nicht möglich.
Ok zugegeben das war etwas unglücklich formuliert.
Die Datensätze insgesamt werden ja jeden Tag mehr. Da ja auch jeden Tag mehr Umsatz geschrieben wird.
Sprich, wenn ich Montag 23.000 Datensätze mit nem Umsatz von 2.800.000€ habe, sind es Mittwoch dann 28.000 Datensätze mit 3.400.000€.

Mit identisch meine ich nur die "alte" Tabelle die automatisch von Access aus der WaWi befüllt wird und einmal die "neue" die ich durch die Anfügeabfrage 1:1 kopiere.
Diese Datensätze müssen ja identisch sein. Und sich auch täglich um die gleiche Anzahl erhöhen.
Das an sich funktioniert auch.

Ich habe eben die Abfrage über SSMS ausgeführt. Gleiches Ergebnis. Datensätze stimmen überein. Umsatz ist um ~71.000€ zu hoch.

ZitatWerden für neue Umsätze ausschließlich neue Datensätze generiert, oder werden bereits bestehende Datensätze auch aktualisiert?
Es werden keine vorhandenen Datensätze geändert. Das ist in unserem System nicht vorgesehen. Es werden lediglich neue hinzugefügt.

ZitatDu bezeichnest deine Abfrage zwar als Aktualisierungsabfrage, aber es ist technisch gesehen eine Anfügeabfrage.
Das hatte ich ja bereits schon korrigiert. Habe mich da nur getäuscht. Natürlich verwende ich eine Anfügeabfrage. Hab nur die Begriffe durcheinander geworfen. Wie gesagt - bin noch nicht so lange im Geschäft.
Beitrag #4
ZitatSelbstverständlich. Habe mich da vertan.

@ebs17
ZitatWenn die Zieltabelle leer ist, kannst Du nden LEFT JOIN nicht nur vergessen, sondern besser gleich streichen. Womit sollen den die Datensätze der Quelltabelle verknüpft werden? Bitte laut beantworten.

Sollten in der Zieltabelle dann doch Daten vorliegen, führt Deine Abfragegestaltung nicht zu einer Einschränktung von Datensätzen, dafür aber zu einer Vervielfältigung der Quelldaten (überall da, wo es in der Zieltabelle den Schlüssel mehr als einmal gibt).

Ich habe keine vervielfältigten Daten. Die Datensätze die bereits vorhanden sind verursachen einen Fehler.
"Access kann nicht alle Datensätze anfügen. XYZ Datensätze wegen Schlüsselverletzung."

Ich weiß, dass das absolut nicht die feine Art ist sowas zu gestalten. Aber dieses Konstrukt wurde von meinem Vorgänger aufgebaut und es soll (momentan) einfach nur funktionieren.
Zumindest solange bis meine Schulungen etc. mich soweit gebracht haben, dass ich weiß wie es besser geht.

ebs17

Zitat...
FROM Kundenumsatz LEFT JOIN dbo_KUNDENUMSATZ
ON Kundenumsatz.SATZ = dbo_KUNDENUMSATZ.SATZ
WHERE dbo_KUNDENUMSATZ.SATZ IS NULL
Mit dieser Prüfung würde man auf vorhanden testen und somit nur neue Datensätze anfügen. Das steht aber im oben verlinkten Beitrag drin und hätte schon Eingang in Dein Selbststudium finden können.

Zitat"Access kann nicht alle Datensätze anfügen. XYZ Datensätze wegen Schlüsselverletzung."
Hier wird sehr wahrscheinlich ein eindeutiger Schlüssel verletzt. Das könnte außer dem betreffenden Feld, das bei der Verknüpfung verwendet wird, auch ein weiteres Feld sein. Schlauer würde man, wenn man seine vorhandene Tabellendefinition mal genauer und unter diesem Gesichtspunkt ansieht.
Mit freundlichem Glück Auf!

Eberhard