Mengensumme für kleinstes Datum

JudAD

Fleissiger Benutzer
Beiträge
71
Hallo,

leider steh ich mal wieder auf dem Schlauch und komme nicht weiter. Ich habe einen SQL Server 2008R2 und möchte gerne aus einer Daten ausgeben. Und zwar hätte ich gerne das kleinste Datum und die dazugehörigen Mengen summiert.

SysNr | Materialnummer | Lieferung | Menge
253941 | 2240830 | 2018-02-22 | 3
253941 | 2240830 | 2018-02-22 | 15
253941 | 2240830 | 2018-02-15 | 18
253941 | 2240830 | 2018-02-15 | 10

Als Ergebnis hätte ich gerne

253941 | 2018-02-15 | 28

Wenn ich folgenden Befehl ausführe erhalte ich:
select SysNr, MIN(Lieferung) as Lieferung, SUM(Menge) as Menge
from Tabelle1
group by SysNr

253941 | 2018-02-15 | 46

Das ist leider falsch, da die Lieferung(en) für 2018-02-15 in Summe 28 ergeben.


Danke vorab
 
Werbung:
Tabelle erstellen:
Code:
create table Tabelle1 (SysNr serial, Materialnummer integer, Lieferung date, Menge integer);

Werte einfügen:
Code:
insert into Tabelle1 (Materialnummer, Lieferung, Menge) Values ('1', '2018-02-18', '5');
insert into Tabelle1 (Materialnummer, Lieferung, Menge) Values ('1', '2018-02-15', '5');
insert into Tabelle1 (Materialnummer, Lieferung, Menge) Values ('1', '2018-02-15', '5');
insert into Tabelle1 (Materialnummer, Lieferung, Menge) Values ('1', '2018-02-15', '5');

Abfragen:
Code:
select SysNr, min(Lieferung), Sum(Menge) from Tabelle1 where Lieferung = '2018-02-15' group by SysNr;

Ich komme hier auf 3 Ergebnisse...

Ich glaube, du vergisst einfach die Where-Klausel in deiner Abfrage ;)

Anhang:
Verwende PostgreSQL, denke aber, dass Abfragen in ein jeder Sprache gleich sein sollten.

EDIT:
Du willst die Mengen summieren, dann muss man die SysNr vollständig rausgeben, dann muss sie auch nicht in der Group by vorkommen. Moment (probieren):
Code:
select min(Lieferung), Sum(Menge) from Tabelle1 where Lieferung = '2018-02-15';

Komme hier auf 15 ;)
 
Zuletzt bearbeitet:
Hallo und Danke für Deine Mühe.

In meiner Beispieltabelle sind es jeweils 2x das Datum 15.02.2018 & 2x das Datum 22.02.2018 - was aber im Grundsatz egal ist. Des Weiteren keinn ich vorher das kleinste Datum nicht, weshalb ich nicht in der Where-Klausel ein fixes Datum eingeben kann! Ich habe auch nur exemplarisch ein Beispiel mit 4 Datensätzen dargestellt. In der Tabelle sind ca. 15000 Datensätze. Ich möchte jedoch das kleinste Datum und wenn es mehrere kleinste Datum gibt (in meinem Beispiel wäre das der 15.02.2018) soll er die Mengen summieren - in deinem Besipiel sollte das Ergebnis so aussehen 1|2018-02-15|15.
 
Dein zweites Beispiel hilft mr leider auch nicht weiter, da ich das Ergebnis für einen weiteren join mit SysNr benötige, und wie gesagt kenn ich vorher das kleinste Datum nicht
 
Code:
select sysnr, min(lieferung), sum(menge) from tabelle1 group by sysnr order by min limit 1

So in etwa?

Bei mir kommt (bei meinem Beispiel) folgendes Raus:
1 - 2018-02-15 - 15

EDIT:
Wenn du das Ganze für andere Erkennbar darstellen willst, würde ich die Spalten noch benennen ;)
Code:
select sysnr as sysnr, min(lieferung) as lieferung, sum(menge) as menge from tabelle1 group by sysnr order by lieferung limit 1
 
SQL Server kennt kein"limit" und ich bin mir auch nicht sicher ob das das Richtige ist. Nach kurzer Suche habe ich herausgefunden dass das T-SQL Äquivalent zu "LIMIT " das "TOP" ist - was aber nur die Ausgabe der Datensätze auf die angebenen Anzahl begrenzt. Wie gesagt stecken in der Tabelle ca. 15000 Datensätze und ich möchte zu jeder SysNr das kleinste Datum mit der dazugehörigen Menge. Wennd as kleinste Datum je SysNr mehrfach vorkommt, dann sollen die Mengen summiert ausgegeben werden.
 
Code:
select min(lieferung), sum(menge), sysnr from tabelle1 group by sysnr

Vl. eine richtige Angehensweise? Aber das geht ohne einem Limit/Top nicht, dass nur ein Datum herauskommt.
Bei meinem Beispiel würde die Abfrage bei meiner Beispieldatenbank 2 Zeilen ausgeben:

2018-02-18 <-> 5 <-> 2
2018-02-15 <-> 15 <-> 1

EDIT: Bin auch kein Profi in sowas, insbesondere Microsoft SQL, aber arbeite gerne mit ;)
 
Hmm, irgendwie werde ich das Gefühl nicht los dass Du meine Frage nicht richtig verstanden hast. In der Tabelle sind 15000 und mehr Datensätze. Zu jeder SysNr kann es hunderte Kombinationen aus Datum und Menge geben. Ich möchte aber nicht exakt einen Datensatz ausgeben sondern zu jeder SysNr das kleinste Datum und die dazugehörige Menge. Wenn es mehrer Datensätze gibt bei denen die SysNr und das kleinste Datum identisch sind (in unserem Beispiel 15.02.2018) sollen bei der Ausgabe die Mengen der identischen Datensätze summiert werden.

Des Weiteren bin ich etwas überrascht das bei Deinem letzten Beispiel plötzlich 2 Datensätze ausgegeben werden sollen obwohl Du über die SysNr gruppierst. Bei mir kommt bei meinem Datenbestand und der selben Abfrage nur ein Datensatz raus und zwar wie im ersten post beschrieben die Summe über aller Datensätze mit der selben SysNr.

So sieht es bei mir aus im Query Analyzer (siehe Screenshot)
 

Anhänge

  • SQL.JPG
    SQL.JPG
    64 KB · Aufrufe: 8
Zuletzt bearbeitet:
Weil ich 2 SysNr habe, in der Datenbank, hatte am Anfang als Serial (auto increment integer) eingerichtet, aber ja ;)

Werde dann mal was anderes machen ^^
Ein Tipp: PostgreSQL :S (Da haben wir einen im Forum, der sich ... ich finde keinen Ausdruck wie gut darin auskennt ;) )
 
Code:
test=*# select * from judad ;
 sysnr  |  matnr  | lieferung  | menge
--------+---------+------------+-------
 253941 | 2240830 | 2018-02-22 |  3
 253941 | 2240830 | 2018-02-22 |  15
 253941 | 2240830 | 2018-02-15 |  18
 253941 | 2240830 | 2018-02-15 |  10
(4 Zeilen)

test=*# select sysnr, lieferung, sum(menge) from judad where lieferung = (select min(lieferung) from judad) group by sysnr, lieferung;
 sysnr  | lieferung  | sum
--------+------------+-----
 253941 | 2018-02-15 |  28
(1 Zeile)

test=*#

Bin mir aber nicht sicher, ob Du Deine Frage korrekt formuliert hast.
 
Hi und auch Dir nochmals Danke. Vielleicht habe ich das nicht - aber ich habe keine Ahnung wie ich es noch besser erklären kann. In meinem Beispiel mit nur einer SysNr in der Tabelle funktioniert DeinBeispiel super - danke dafür. Nur sobald ich den Befehl auf die gesamte Tabelle lasse kommt wieder ein falsches Ergebnis raus. Ich habe mal eine neue Tabelle mit 8 Datensätzen je 4 Datensätzen zu einer SysNr gemacht, sprich:

sysnr | matnr | lieferung | menge
--------+---------+------------+-------
253940 | 2240830 | 2018-02-22 | 3
253940 | 2240830 | 2018-02-22 | 15
253940 | 2240830 | 2018-02-12 | 18
253940 | 2240830 | 2018-02-12 | 10
253941 | 2240830 | 2018-02-22 | 3
253941 | 2240830 | 2018-02-22 | 15
253941 | 2240830 | 2018-02-15 | 18
253941 | 2240830 | 2018-02-15 | 10

Ergebnis sollte sein
--------+------------+-----
253940 | 2018-02-12 | 28
253941 | 2018-02-15 | 28

Wenn ich Dein Befehl auf diese Tabelle mache erhalte ich

--------+------------+-----
253940 | 2018-02-12 | 28

Ist das nun etwas klarer?
 
Er sucht
Code:
SELECT   t1.SysNr,
     min(t1.Lieferung) AS Lieferung,
     sum(t1.Menge) AS Menge
FROM   tabelle1 t1
WHERE   Lieferung = ( SELECT min(t2.Lieferung) FROM tabelle1 t2 WHERE t2.SysNr = t1.SysNr )
GROUP BY t1.SysNr
253941 2018-02-15 28
 
Zuletzt bearbeitet:
Code:
test=*# select * from judad ;
 sysnr  |  matnr  | lieferung  | menge
--------+---------+------------+-------
 253941 | 2240830 | 2018-02-22 |  3
 253941 | 2240830 | 2018-02-22 |  15
 253941 | 2240830 | 2018-02-15 |  18
 253941 | 2240830 | 2018-02-15 |  10
 253940 | 2240830 | 2018-02-22 |  3
 253940 | 2240830 | 2018-02-22 |  15
 253940 | 2240830 | 2018-02-12 |  18
 253940 | 2240830 | 2018-02-12 |  10
(8 Zeilen)

test=*# select sysnr, lieferung, sum(menge) from judad where (sysnr, lieferung) in (select sysnr, min(lieferung) as lieferung from judad group by sysnr) group by sysnr, lieferung;
 sysnr  | lieferung  | sum
--------+------------+-----
 253940 | 2018-02-12 |  28
 253941 | 2018-02-15 |  28
(2 Zeilen)

test=*#
 
Werbung:
akretschmers Lösung auch nur du kannst in MSSQL keine zwei Atribute mit zwei anderen Werten per IN-Operator vergleichen. Es spricht aber auch nichts gegen ein WHERE im Subselect mit Bezug auf den äußeren Select.
 
Zurück
Oben