![]() |
Datenbank: Firebird • Version: 3.x • Zugriff über: IBDAC
[SQL] Wie Gruppensumme bilden?
Ich habe eine Tabelle, in der Vorgangspositionen (die einzelnen Artikel einer Rechnung) enthalten sind. Diese möchte ich zusammengefasst (group by) nach ArtikelNr ausgeben. Zu jeder ArtikelNr sollen weitere Felder ausgeben werden, so wie hier:
Code:
Das klappt gut. Sieht z.B. so aus:
select
substring(ArtikelNr from 1 for 5) as "Gruppe", ArtikelNr, max(Beschreibung) as Beschreibung, max(Farbe) as Farbe, sum(Menge) as Menge, sum(NettoSumme) as NettoSumme from VorgangPos vp group by ArtikelNr order by ArtikelNr
Code:
Gruppe ArtikelNr Beschreibung Farbe Menge NettoSumme
12345 12345-7 Mauspad blau 2 12,- 12345 12345-14 Maus grau 3 50,- 45678 45678-2 Tastatur grau 1 70,- Jetzt möchte ich zusätzlich noch zu jeder ArtikelNr, die die selbe Gruppe hat, die Gesamtsumme aller Mengen in dieser Gruppe ausgeben. Z.B. so:
Code:
Mein Versuch sieht so aus:
Gruppe ArtikelNr Beschreibung Farbe Menge NettoSumme Gruppenmenge
12345 12345-7 Mauspad blau 2 12,- 5 (da 2+3 =5) 12345 12345-14 Maus grau 3 50,- 5 (da 2+3 =5) 45678 45678-2 Tastatur grau 1 70,- 1
Code:
Über Delphi läuft das endlos (nach 10 Minuten aufgegeben). Mit dem IBExpert ist das auch nicht ausführbar, der friert dann ein, wenn er das Ergebnis anzeigen möchte.
select
substring(ArtikelNr from 1 for 5) as "Gruppe", ArtikelNr, max(Beschreibung) as Beschreibung, max(Farbe) as Farbe, sum(Menge) as Menge, sum(NettoSumme) as NettoSumme, min(( select sum(Menge) from VorgangPos vpSub where substring(vpSub.ArtikelNr from 1 for 5) = substring(vp.ArtikelNr from 1 for 5) )) as Gruppenmenge from VorgangPos vp group by ArtikelNr order by ArtikelNr Die Gruppe ist (leider) in der ArtikelNr gespeichert. Es kann nichts an der Datenstrutkur geändert werden. Der Bindestrich dort ist nur zur besseren Übersicht eingefügt. Was mache ich falsch? Wie geht's richtig? Danke! |
AW: [SQL] Wie Gruppensumme bilden?
Man würde hier einen INNER oder LEFT OUTER JOIN von VorgangPos auf VorgangPos machen:
Code:
select
substring(vp.ArtikelNr from 1 for 5) as "Gruppe", vp.ArtikelNr, max(vp.Beschreibung) as Beschreibung, max(vp.Farbe) as Farbe, sum(vp.Menge) as Menge, sum(vp.NettoSumme) as NettoSumme, sum(vp2.Menge) Gruppenmenge from VorgangPos vp inner join VorgangPos vp2 ON substring(vp2.ArtikelNr from 1 for 5) = substring(vp.ArtikelNr from 1 for 5) group by vp.ArtikelNr order by vp.ArtikelNr |
AW: [SQL] Wie Gruppensumme bilden?
Zitat:
|
AW: [SQL] Wie Gruppensumme bilden?
bringt es was, wenn Du substring()durch left(vp.ArtikelNr, 5) ersetzt?
Grüße Klaus |
AW: [SQL] Wie Gruppensumme bilden?
Dashier kann nicht schnell sein:
SQL-Code:
Je Datensatz der Ergebnismenge muss ein Subselect mit einer Einschränkung auf einen Teilstring gemacht werden, für den es (vermutlich / höchstwahrscheinlich) keinen Index gibt.
min((
select sum(Menge) from VorgangPos vpSub where substring(vpSub.ArtikelNr from 1 for 5) = substring(vp.ArtikelNr from 1 for 5) )) as Gruppenmenge Bevor wir nach anderen Lösungen für den Aufbau der Abfrage suchen, probiere es bitte mal mit
SQL-Code:
create index ix_VorgangPos_Gruppe on VorgangPos computed by (substring(ArtikelNr from 1 for 5))
|
AW: [SQL] Wie Gruppensumme bilden?
In Form einer SP/einem Codeblock:
SQL-Code:
...for select
substring(vp.ArtikelNr from 1 for 5), vp.ArtikelNr, max(vp.Beschreibung) as Beschreibung, max(vp.Farbe) as Farbe, sum(vp.Menge) as Menge, sum(vp.NettoSumme) as NettoSumme from VorgangPos vp into :gruppe, ArtikelNr, :... do begin for select sum(Menge) from VorgangPos where substring(ArtikelNr from 1 for 5) = Gruppe into :Gruppenmenge do suspend; end |
AW: [SQL] Wie Gruppensumme bilden?
"Richtig" wäre nach meinem Bauchgefühl mit Windowing Funktionen zu arbeiten:
![]() Dabei setzt man eine partition auf die gewünschten Gruppen und kann dann je Gruppe mit Aggregatfunktionen arbeiten. Vielleicht kann hier im Forum das für Firebird (3) kurz in SQL giessen. p.s. ich habe Windowing mit MS SQL / Oracle / DB2 bereits eingesetzt und eine Gruppenmenge sollte damit problemlos und vor allem sehr performant realisierbar sein. Vielleicht kann ich es in den nächsten Tagen an einer Beispiel-DB zeigen. |
AW: [SQL] Wie Gruppensumme bilden?
Wenn durch eine solche Abfrage ein paar GB gedumped werden und alles so ewig dauert, dann mal so ins Blaue:
Vielleicht ein Join Kriterium vergessen? Wenn die Daten trotz Gruppierung mehr werden kann irgendwas nicht stimmen. Die Variante von Reedemer (äußerer Join) würde ich jedenfalls vorziehen. Wenn fb Partition Windows kann, dann wohl das. Die Partition / Gruppierung & Join anhand eines Teilstrings zu machen, ist natürlich generell nicht die Grundlage für irrsinnige Geschwindigkeit. |
AW: [SQL] Wie Gruppensumme bilden?
Zitat:
|
AW: [SQL] Wie Gruppensumme bilden?
Wenn es so lange läuft, wird der Index nicht genutzt. Der dient je gerade dazu, die Komplexität logarithmisch zu begrenzen.
Ein paar Ideen, je nachdem, was dein DBMS kann:
|
Alle Zeitangaben in WEZ +1. Es ist jetzt 08:28 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz