SQL "sum" in bestimmtem Zeitraum

wuffli

Benutzer
Beiträge
15
Hallo :)

Ein Hersteller wünscht das ich ihm wöchentlich Meldung mache was ich Lager habe und ich in dem Zeitraum verkauft habe. Ich habe nun zwar ein Script geschrieben das mir anzeigt was alles im besagten Zeitraum verkauft wurde und was der Lagerbestand dieser Artikel ist, aber ich bringe es nicht hin das er mir den Lagerbestand der anderen Artikel ebenfalls anzeigt.

Ich habe bei der where clausel das Datum drin, dann bekomme ich allerdings nur die Ausgabe der Artikel welche effektiv in diesem Zeitraum eine Mutation hatten.
Wenn ich bei select den Befehl "between" anfüge bekomme ich auch nicht das richtige Ergebnis. Ich gehe davon aus das er mir dort das Datum einer falschen Tabelle abfragt.
Da ich ziemlich neu in dem Bereich bin weiss ich nicht ob man das überhaupt miteinander verknüpfen kann?

Hier mal mein bisheriger Code um das wirre geschwafel etwas besser zu verstehen. ;)

Code:
select year(AH.GEAND) as Jahr, weekofyear(AH.GEAND) as KALENDERWOCHE, a.kurzname as Bezeichnung, a.barcode as EAN, sum(abs(AH.MENGE_GEBUCHT)) as Verkauft, A.Menge_Akt as Lager
from Artikel A
left join artikel_historie AH on AH.ARTIKEL_ID = a.rec_id
where a.kurzname like "%sony%"
AND a.barcode > "1000000"
AND AH.GEAND between '2015-11-01' and '2015-11-08'
group by ah.artikel_id
order by ah.geand asc
 
Werbung:
Das ist syntaktisch falsch, mit der aktuellen MySQL 5.7 fliegt Dir das schon mit einer Fehlermeldung um die Ohren, in quasi allen anderen Datenbanken der Welt schon seit ca. 150 Jahren. Alle Spalten im resultat müssen entweder aggregiert oder gruppiert werden.
 
Hi, und danke für deine Antwort.
Die Software nutzt leider noch MySQL 4.0.26. Ich weiss, steinalt, aber aus irgend einem Grund können die nicht updaten.
 
Die gibt es schon, aber mit der alten Struktur, dem angebundenem Online-Shop, allen Formularen etc. ist das ein Aufwand den ich in nächster Zeit nicht nachkommen kann. :/
 
Die Software nutzt leider noch MySQL 4.0.26. Ich weiss, steinalt, aber aus irgend einem Grund können die nicht updaten.

Oh! Mein! Gott!

Wie viele Jahre ist das schon nicht mehr supportet? Und ihr betreibt einen Onlineshop? Gruselig.


Zeig wenigstens mal die Struktur der beteiligten Tabellen. Warum stehen da offenbar in den Stammdaten (Artikel) Bewegungsdaten (Menge_gebucht) drin?
 
Aber damit kannst du den Hersteller evtl. dazu drängen seine Software zu aktualisieren.
Naja das nützt nichts, das wird schon lange versucht, ich hab da resigniert.

Oh! Mein! Gott!

Wie viele Jahre ist das schon nicht mehr supportet? Und ihr betreibt einen Onlineshop? Gruselig.


Zeig wenigstens mal die Struktur der beteiligten Tabellen. Warum stehen da offenbar in den Stammdaten (Artikel) Bewegungsdaten (Menge_gebucht) drin?

Das wird immer noch Supportet, das Programm wird rege weiter entwickelt und ausgebaut, einfach auf Basis dieser alten SQL. Shop läuft mit Shopware und wird über eine Schnittstelle gekoppelt, das sollte also keineswegs gruselig sein.

Was genau musst du von mir haben? Die ganze Struktur ist riesig und wohl etwas zu gross um hier rein zu schreiben. Es geht ja auch rein darum ob man so verschachtelt kombinieren kann oder nicht?
die Menge gebucht steht in Artikel_Historie (ah) und nicht in den Stammdaten Artikel (a). Aber vielleicht mach auch ich da einen Fehler, wie gesagt bin nicht ganz sattelfest.
 
Angenommen, Du hast diese Tabellen und Daten:

Code:
test=*# select * from artikel ;
 id |  name
----+-----------
  1 | artikel 1
  2 | artikel 2
  3 | artikel 3
(3 rows)

test=*# select * from bestand ;
 artikel | menge |  datum
---------+-------+------------
  1 |  -5 | 2015-11-01
  1 |  15 | 2015-11-05
  1 |  -3 | 2015-11-10
  1 |  30 | 2015-11-15
  2 |  5 | 2015-11-01
  2 |  15 | 2015-11-12
  2 |  -17 | 2015-11-13
  3 |  20 | 2015-11-03
  3 |  2 | 2015-11-13
(9 rows)

In bestand sind die Bewegungen, negativ ist verkauft, positiv ist Lagerauffüllung.

Code:
test=*# select a.name, sum(case when b.menge < 0 then b.menge else 0 end) as verkauft, sum(case when b.menge > 0 then b.menge else 0 end) as gekauft from artikel a left join bestand b on a.id=b.artikel group by a.name order by a.name;
  name  | verkauft | gekauft
-----------+----------+---------
 artikel 1 |  -8 |  45
 artikel 2 |  -17 |  20
 artikel 3 |  0 |  22
(3 rows)

Wenn das für einen bestimmten Zeitraum eingeschränkt werden soll dann kommt das in die Where-Condition. Da Du offenbar eine Spalte in artikel mit dem jeweiligen aktuellen Bestand hast brauche ich das hier nicht weiter zu behandeln.
 
Du hast in Deiner Lösung ein sum(abs(...)), falls da wie hier Zu- und Abgänge positiv/negativ gebucht werden macht Du alles zu Zubuchungen. Das ist also dann schon mal grundsätzlich unüberlegt.
 
abs hab ich nur genommen weils schöner dargestellt kommt. Schlussendlich sieht er in der Tabelle "Verkauft" wie viele Stück in dem Zeitraum verkauft wurden und das wär mit negativen Zahlen unschön.

Das Problem an der Where-Condition ist dass es sich auf alle Anfragen ausübt, ich möchte aber alle Einträge anzeigen lassen und nur die zusammenrechnen, welche im besagten Zeitraum verkauft wurden.

etwas in der Art ist nicht möglich, oder?
Code:
select
case when Datum between'2015-11-01' and '2015-11-08' then sum(menge) as verkauft
Ich krieg hier einen SQL Syntaxfehler weil ich das wohl nicht so kombinieren darf?
 
Zuletzt bearbeitet:
aber alle Einträge anzeigen lassen und nur die zusammenrechnen, welche im besagten Zeitraum verkauft wurden.

Entweder zeigst Du alle an (egal ob auf Zeitraum begrenzt oder nicht) oder rechnest diese zusammen. Wenn Du die zusammenrechnen willst (aggregieren), dann muß Du die anderen Spalten gruppieren. Wenn Du das nicht machst - funktioniert die Abfrage in MySQL dennoch, liefert aber Bullshit. Kurzdemo.

Du hast diese Tabelle mit Spielern und deren Tore:

Code:
mysql> select * from fussball;
+---------+------------+------+
| vorname | nachname  | tor  |
+---------+------------+------+
| max  | mustermann |  1 |
| max  | rabe  |  1 |
| susi  | sorglos  |  1 |
+---------+------------+------+
3 rows in set (0.03 sec)

Nun eine Abfrage, die ähnlich falsch ist wie Deine:

Code:
mysql> select vorname, nachname, sum(tor) from fussball group by vorname;
+---------+------------+----------+
| vorname | nachname  | sum(tor) |
+---------+------------+----------+
| max  | mustermann |  2 |
| susi  | sorglos  |  1 |
+---------+------------+----------+
2 rows in set (0.03 sec)

Offensichtlich falsch, weil Max Mustermann nur 1 Tor geschossen hat. Oder?

Das ist ein seit Anfang an in MySQL vorhandener Fehler, der in 5.7 nun ENDLICH mal dahingehend gefixt ist, daß da (meines Wissens nach) ein Fehler kommt. Kann mal jemand das mit 5.7 nachstellen? Was passiert? Andere Datenbanken verweigern schon immer solch falsche Abfragen.
 
Weiss nicht ob wir uns jetzt richtig verstanden haben.
Ich möchte alle anzeigen aber nur die im Zeitraum zusammenrechnen (siehe unten). Das mit der Abfrage würde sich allerdings bei meiner Tabelle Eindeutig zuordnen lassen da jeder Artikel eine spezielle ID kriegt die unikat ist.

Angenommen das ist die Tabelle neu mit ID und Datum der Ereignises
Code:
+---------+------------+------+
| ID | vorname | nachname | tor | Datum |
+---------+------------+------+
| 1 | max | mustermann | 1 | 01.01.2015 |
| 2 | max | rabe | 1 | 05.01.2015 |
| 1 | max | mustermann | 1 | 05.01.2015 |
| 3 | susi | sorglos | 1 | 12.01.2015 |
| 1 | max | mustermann | 1 | 20.01.2015 |
+---------+------------+------+

Dann hätte ich gerne folgendes Ergebnis

Code:
mysql> select vorname, nachname, sum(tor) from fussball where Datum between '01.01.2015' and '10.01.2015 group by ID;
+---------+------------+----------+
| vorname | nachname | sum(tor) |
+---------+------------+----------+
| max | mustermann | 2 |
| max | rabe | 1 |
| susi | sorglos | 0 |
+---------+------------+----------+

Nur ist hier das Problem das beim 'where' die Susi normalerweise nicht angezeigt wird.
 
Code:
test=*# select * from wuffi ;
 id |  v  |  n  | tor |  datum
----+------+------------+-----+------------
  1 | max  | mustermann |  1 | 2015-01-01
  2 | max  | rabe  |  1 | 2015-01-05
  1 | max  | mustermann |  1 | 2015-01-05
  3 | susi | sorglos  |  1 | 2015-01-12
  1 | max  | mustermann |  1 | 2015-01-20
(5 rows)

test=*# select v, n, sum(case when datum between '2015-01-01' and '2015-01-10' then tor else 0 end) as tore from wuffi group by v, n;
  v  |  n  | tore
------+------------+------
 max  | rabe  |  1
 max  | mustermann |  2
 susi | sorglos  |  0
(3 rows)

sollte sogar mysql können ;-)
 
Werbung:
Zurück
Oben