SQL Tabelle in andere Tabelle konsolidieren

DenSe

Cadet 3rd Year
Registriert
Okt. 2016
Beiträge
35
Hallo liebe Base'ler,

Ausgangssituation:
Ich habe folgende Tabellen:
artikel:
lfdnrpreiswghostnametimestamp
22.00130C1597NB05132017-04-12 10:19:21.000000
31.00130C1597NB05872017-04-12 10:23:46.000000

und
verkauf:
artikelnrpreiswgmenge
12.001301

Ich führe einen Verkauf durch, bei dem wie in einem Geschäft jeder Artikel gescannt wird und dann die Daten "preis" und "wg" (wg = Warengruppe) von einem Barcode kommen, der "timestamp" und der "hostname" dienen nur der Eindeutigkeit des Datensatzes.
In die Tabelle "artikel" wird dann jeder einzelne Artikel einzeln untereinander geschrieben.

Problem:
Die Daten aus "artikel" müssen in der Tabelle "verkauf" konsolidiert werden.
in "verkauf" wird die "artikelnr" automatisch inkrementiert. Dann muss eine Kombination aus "preis" und "wg" aus "artikel" genommen werden und gezählt werden. Daraus resultiert die "menge". Weiteres Problem dabei ist, mit welcher kombination aus "preis" und "wg" fange ich am besten an? Von oben immer der erste? Was mache ich mit den Datensätzen, die ich bereits kopiert habe? Sollte ich die am besten löschen? Denn es kommen immer wieder neue Datensätze sehr schnell hinzu. Mit großer Wahrscheinlichkeit auch gleiche Kombinationen aus "preis" und "wg", die ich ja dann noch nicht in die Tabelle "verkauf" geschrieben habe.
Diese Prozedur möchte ich gerne alle 2 Minuten automatisch mit einem Cronjob durchführen lassen.

Ich hoffe, ich konnte mein Problem verständlich formulieren. Bei unverständnis einfach Fragen.

Mir fehlt im Moment jeglicher Ansatz, mit welchen SQL-Befehlen ich diese Problem lösen könnte.

Schreibe ich mir am besten eine Prozedur oder was?

Vielen Dank für eure Hilfe.

Gruß DenSe :cool_alt:
 
Hi,

mir persönlich hilft es immer eine Beispiel-Tabelle des gewünschten Endergebnisses daneben zu legen.
Dann kann man über Vor/Nachteile diese Lösung diskutieren und es gibt keine schwer zu lesende Textwand.

Ansonsten:
Abkürzungen rächen sich meiner Erfahrung nach später. Lieber ausschreiben als raten müssen was "wg" bedeuten soll.
Hier rächt es sich IMHO, faul zu sein! (Und ich bin sehr gerne faul!)

hth
 
Die Artikelnummer wird inkrementiert? Wtf? Dann ist das keine Artikelnummer, sondern eine Zeilennumer.... Das Datenmodell ist mal ziemlich bescheiden, um es mal freundlich auszudrücken.

Das sieht für mich danach aus, als wenn angenommen wird, dass eine eindeutige Kombination aus Preis und Warengruppe auf einen Artikel schließen lässt. Was ist denn, wenn es in einer Warengruppe 2 Artikel mit dem selben Preis gibt?

select preis, wg, count(*) Into verkauf from artikel group by preis, wg wäre ein ansatz, wenn artikelnr in Verkauf auch selbst inkrementiert.
 
Zuletzt bearbeitet:
@nyromant
Ich habe ja schon eine Endtabelle mit ins Posting getan und hab sie die ganze Zeit vor Augen.

@drexel
Ja die Artikelnummer wird inkrementiert und JA ein Artikel wird Eindeutig durch die Kombination aus Preis und Warengruppe. Wenn wir 2 Artikel haben die beide Warengruppe '130' sind und beide 2,00 € kosten dann stehen die beide so in der Tabelle "artikel" drin. Der Datensatz wird ja trotzdem Einzigartig durch den Hostname und den Timestamp.
In der Tabelle "verkauf" soll es dann nur noch einen Datensatz mit der Kombination Warengruppe '130' und Preis 2,00€ geben und dort immer nur die Menge aufaddiert werden. Diese ergibt sich ja durch die zählung der Einträge die man erhält wenn man folgendes Abfragt:
Code:
select preis, wg from artikel where preis = 2.00 and wg = '130';

Dein Select-Befehl gibt mir eine Fehlermeldung bei mir aus. Er denkt verkauf sei eine nicht deklarierte Variable anstatt tabelle.
 
Das macht das Tabellendesign nicht besser. Ja jede Zeile in der Artikel Tabelle ist eindeutig, Du weißt aber trotzdem nicht um welchen Artikel es sich konkret handelt, wenn wg und preis gleich sind. Genauso wie Du in der Verkauf Tabelle nicht merkst, dass sich hinter einer Zeile verschiedene Artikel verbergen, wenn wg und preis gleich sind. Ich weiß ja nicht wofür das ist, aber brauchbare Auswertungen scheinen mir da nicht möglich zu sein.

Dein Statement müsste eher so aussehen:
Code:
select preis, wg from artikel where preis = 2.00 and wg = 130;
Warum da eine Fehlermeldung mti verkauf kommt, weiß ich nicht, verkauf kommt in dem Statement ja gar nicht vor. Es wäre auch Hilfreich, die Fehlermeldung einfach mal zu posten und nicht nur Deine Interpretation was der Computer "denkt", ich vermute in dem Moment ist schon 90% der wesentlichen Informationen verloren gegangen. Über was für ein DBMS reden wir hier eigentlich?

Nochmal eine Nachbesserung zu oben. So müsste es ungefähr heißen:
Code:
INSERT INTO verkauf (preis, wg, menge)
select preis, wg, count(*) from artikel group by preis, wg;

PS: nyromant Einwand ist in sofern berechtigt, dass man aus Deinem ersten Post kaum entnehmen kann, was Du willst, die wesentliche Zusammenhänge erklärst Du nicht...
 
Ich habe mir das Tabellendesign auch nicht ausgedacht, ich entwickele nur die Software dahinter. Ich muss halt damit arbeiten. Nein ich kann nicht sagen, ob der Artikel '130', 2,00€ ein Löffel oder ein Plastikbecher ist. Das ist aber für unsere Auswertung später egal, da eine genaue Artikelbezeichnung unseren zeitlichen Aufwand für dieses Projekt sprengen würde. In der Tabelle "verkauf" werden ja nur die Mengen gezählt. Unsere Auswertung sieht vor, dass wir den Gesamt-Umsatz pro Warengruppe dokumentieren, mehr nicht.

Folgende Fehlermeldung kommt wenn ich eingebe:
Code:
MariaDB [verkauf_0417]> select preis, wg, count(*) Into verkauf from artikel group by preis, wg;
Code:
ERROR 1327 (42000): Undeclared variable: verkauf

Es handelt sich übrigens um eine 10.0.21-MariaDB.

Mein Problem an der Stelle ist, wie ich am besten Anfangen kann aus der Tabelle "artikel" die Kombinationen aus Preis und Warengruppe herausziehen kann um diese dann in "verkauf" als so darzustellen. Da muss ich ja jede Kombination durchgehen, die es gibt. Dann frage ich mich, was mach ich mit den Datensätzen in "artikel" die ich bereits erfolgreich übernommen habe. Außerdem kommen ja ständig neue Datensätze hinzu, wie kann unterscheiden, ob ich einen Datensatz schon konsolidiert habe oder nicht?

P.S. ich glaube dein Code bringt mir den erhofften Erfolg. Ich teste das mal durch.
Ergänzung ()

Deine Lösung funktioniert.
Das ist genau das was ich brauchte.

Danke für deine Mühe und deine Nerven:D
 
Das Statement aktualisiert vorhandene Datensätze aber nicht, Du müsstest die Tabelle Verkauf im Zweifel vorher noch leeren...

DenSe schrieb:
Unsere Auswertung sieht vor, dass wir den Gesamt-Umsatz pro Warengruppe dokumentieren, mehr nicht.

Das machst Du mit der Ausgabe aber nicht, Du errechnest den Umsatz (bzw. Preis und Menge woraus man den Umsatz dann leicht errechnen kann) pro Warengruppe und Preis. :)
 
Zuletzt bearbeitet:
Ja das habe ich gemerkt. Ich kann auch bei der schnelligkeit an Daten nicht garantieren, dass nicht Datensätze verloren gehen oder doppelt übernommen werden, wenn ich das alle 2 minuten machen will.
 
Dass nichts verloren geht, dafür sorgt das DBMS, ist ja nur ein Statement.
Wenn Du vorher die Tabelle leerst und dann wieder füllst, kann es natürlich sein, dass jemand in dem Moment eine Auswertungsanfrage schickt, wo die Tabelle leer ist. Das könntest Du mit Transaktionen verhindern. Unter Umständen kann das natürlich weitere Requests blocken, je nachdem wie lange das Leeren und Füllen dauert kann das unschön werden.

Das könnte man wiederum verhindern, in dem man 2 Tabellen hat, eine produktive und eine die aktualisiert wird und nach der Aktualisierung wird ein Link auf die Tabelle geupdatet, der dann auch in den Abfragen natürlich benutzt werden muss. Das sind aber schon DWH Techniken.

Oder Du musst Dir was überlegen, wie Du die Datensätze nur für geänderte Daten aktulisierst, evtl. mit nem Trigger oder sowas.

Das sind so Themen mit denen sich Datenbankexperten den ganzen beschäftigen. :)
 
DenSe schrieb:
Ich kann auch bei der schnelligkeit an Daten nicht garantieren, dass nicht Datensätze verloren gehen oder doppelt übernommen werden, wenn ich das alle 2 minuten machen will.
Deswegen könntest Du in die Tabelle Verkauf vielleicht eine Spalte Timestamp einbauen, aus der Du erkennen kannst, welche verkauften Artikel bereits ausgewertet wurden. Bei der Aktualisierung berücksichtigst Du dann nur neuere Einträge.
 
Zurück
Oben