creamycewie
Goto Top

TSQL - Summe pro Feld als zusätzliche Spalte

Hallöchen.

Ich habe folgendes Select-Statement:

select Belegtyp, AdressNr, Menge, Artikelnummer, Gesamtpreis as 'VK pro POS' from Belegp where Belegtyp = '0' and Datum = :Datum and Mitarbeiter  = :Vertreter  or Belegtyp = 'F' and Datum = :Datum and Mitarbeiter  = :Vertreter order by AdressNr  

Mit diesem Statement hole ich mir alle DS aus 2 Tabellen, gefiltert nach ein paar Kriterien.

Als Ergebnissmenge bekome ich folgendes:
Belegtyp AdressNr Menge Artikelnummer VK pro POS
0 111048 10,00 2800_320 840,00
F 111048 1,00 3306 0,25
0 112116 1,00 1000 14,90
0 112116 3,00 1007 50,40
0 112116 5,00 1022 159,50
F 112116 3,00 1007 50,40
F 112116 5,00 1022 159,50
F 112116 1,00 3,13 14,90

Ergebniss ist soweit korrekt.
Nun brauche ich jedoch noch 2 Spalten die folgendes beinhalten:

1.) Ich brauche nun eine Spalte "Gesamt pro AdressNr" in der folgendes enthalten sein soll:
eine Summe aller "VK pro POS" (jedoch nur wenn Belegtyp = "F"), und zwar pro AdressNr.

2.) Ich brauche nun eine Spalte "Gesamt ALLE" in der folgendes enthalten sein soll:
eine Summe aller "VK pro POS" (jedoch nur wenn Belegtyp = "F"), egal welche AdressNr eingetragen ist

Zur Veranschaulichung, so sollte die Ergebnissmenge dann aussehen:

Belegtyp AdressNr Menge Artikelnummer VK pro POS Gesamt pro AdressNr Gesamt ALLE
0 111048 10,00 2800_320 840,00 0,25 225,05
F 111048 1,00 3306 0,25 0,25 225,05
0 112116 1,00 1000 14,90 224,80 225,05
0 112116 3,00 1007 50,40 224,80 225,05
0 112116 5,00 1022 159,50 224,80 225,05
F 112116 3,00 1007 50,40 224,80 225,05
F 112116 5,00 1022 159,50 224,80 225,05
F 112116 1,00 3,13 14,90 224,80 225,05

wie lassen sich diese 2 berechneten Spalten realisieren?

Lieben Dank!

Content-Key: 453768

Url: https://administrator.de/contentid/453768

Ausgedruckt am: 28.03.2024 um 20:03 Uhr

Mitglied: Crusher79
Crusher79 20.05.2019 aktualisiert um 17:01:10 Uhr
Goto Top
Hi,

man nimmt verschachtleten SELECT. Habe greade keine Zeit es zu schreiben. Hier mal eine BAR / UNBAR Spalte für Kassenabrechnung.

Ggf. musst du auch NUL berücksichtigen.

Kurz: Geheimnis ist SELECT und SUM OVER () ! Hier musst du für das erste Beispiel natürlich mit SUM (VK pro POS ) OVER (PARTITION BY AdressNr) arbeiten!

Dann wird schon nach Adresse gruppiert und Du hast as richtige Ergebnis. Die Summe überalles ist natürlich einfacher.

Mach die 2 SELECT erstmal einzeln + WHERE Part. Dann kopierst du es einfach in deinen 1. SELECT mit rein.

, ISNULL((SELECT TOP 1 SUM(Total) OVER() AS 'EC-Total' FROM[kpw_intra].[dbo].[eup] p WHERE PaymentType = '4' AND Datum = '20190520' ),0) AS 'EC_Karte'"  
, SUM(GesamtPreis) OVER() AS 'Ges_Umsatz', (SELECT TOP 1 Zeit FROM [kpw_intra].[dbo].[euc] WHERE Datum='20190520' order by Zeit desc) AS 'Zeit  
', (SELECT TOP 1 BonNr FROM [kpw_intra].[dbo].[euc] WHERE Datum='{0}' order by BonNr desc) AS 'BonNr'  


Ok, habs doch nochmal probiert. Versucht mal das:

select Belegtyp, AdressNr, Menge, Artikelnummer, Gesamtpreis as 'VK pro POS'   
, (SELECT SUM (Gesamtpreis) OVER (PARTITION BY AdressNr) AS 'Gesamt pro AdressNr' FROM Belegp WHERE Belegtyp = "F")  
, (SELECT SUM (Gesamtpreis) OVER () AS 'Gesamt ALLE' FROM Belegp WHERE Belegtyp = "F")  
from Belegp where Belegtyp = '0' and Datum = :Datum and Mitarbeiter  = :Vertreter  or Belegtyp = 'F' and Datum = :Datum and Mitarbeiter  = :Vertreter order by AdressNr  
Mitglied: em-pie
em-pie 20.05.2019 aktualisiert um 20:48:00 Uhr
Goto Top
Moin,

Variante 2 wäre:

select 
	Belegp.Belegtyp
	, Belegp.AdressNr
	, Belegp.Menge
	, Belegp.Artikelnummer
	, Belegp.Gesamtpreis as 'VK pro POS'  
	, ISNULL(sumadress.SumAdress, 0) As SumAdress
	, ISNULL(sumbeleg.SumBelegF, 0) as SumBelegF
from Belegp 
where 
	(Belegtyp = '0' and Datum = :Datum and Mitarbeiter  = :Vertreter)    
	or (Belegtyp = 'F' and Datum = :Datum and Mitarbeiter  = :Vertreter)   
LEFT JOIN (Select AdressNr, SUM(VK_pro_POS) as SUM_Adress WHERE Belegtyp = 'F' GROUP BY AdressNr ) as sumadress   
	on Belegp.AdressNR = sumadress.AdressNr
LEFT JOIN (Select Belegtyp, SUM(VK_pro_POS) as SumBelegF WHERE Belegtyp = 'F' GROUP BY Belegtyp ) as sumbeleg   
	on Belegp.Belegtyp = sumadress.SumBelegF
order by AdressNr

Durch die Joins muss das Subselect nicht bei jedem Datensatz "neugebildet" werden, wenn ich mich da recht erinnere. Denn eine Tabelle innerhalb eines Joins wird IMHO nur zum Zeitpunkt des "ersten" Aufrufes gebildet.
Wobei sich das nicht pauschal sagen lässt, da es ja immer von den zu behandelnden Daten(mengen) abhängt

Gruß
em-pie
Mitglied: ukulele-7
ukulele-7 20.05.2019 um 18:44:43 Uhr
Goto Top
Variante 2 ist auf jeden Fall zu bevorzugen.

Kritisieren würde ich das aber dennoch da einfach gar nicht sinnvoll gruppiert wird. Wer braucht denn eine Liste mit Positionen in der die Summe von Positionen in jeder Zeile steht? Das klingt für mich doch arg nach Fusch. Besser wäre vielleicht eine (oder zwei) Summenzeilen oder eine laufende Summe je nach Anwendungszweck.
Mitglied: MadMax
MadMax 20.05.2019 um 18:44:56 Uhr
Goto Top
Moin,

der Ansatz mit den Fensterfunktionen ist zwar richtig, aber es geht auch ohne zusätzliche Selects:
select Belegtyp, AdressNr, Menge, Artikelnummer, Gesamtpreis as 'VK pro POS',  
	sum (case Belegtyp when 'F' then Gesamtpreis else 0 end) over (partition by AdressNr) as Gesamt_pro_AdressNr,  
	sum (case Belegtyp when 'F' then Gesamtpreis else 0 end) over () as Gesamt_ALLE  
from Belegp 
where (Belegtyp = '0' and Datum = :Datum and Mitarbeiter  = :Vertreter)  or (Belegtyp = 'F' and Datum = :Datum and Mitarbeiter  = :Vertreter)   
order by AdressNr

Gruß, Mad Max
Mitglied: Crusher79
Crusher79 20.05.2019 um 22:20:51 Uhr
Goto Top
Aber es funktioniert....

Bei mir war es zusätzliche Übersicht zum Kassenystem (nur Bon-Drucker).

Bei 70-80 Belegen pro Tag reicht sowas völlig. Komt auch drauf an, welche Programmiersprache ggf. mitschwingt: C#, etc. oder ein 4 GL.

Bei der Variante ist das schöne, dass man mit einen einzigen Datensatz alles beisammen hat. Kommt immer drauf an, was man machen will. Das Ergebnis zumindest ist sauber.

Mutmaße beim Fragesteller, dass er auch eher mit geringen Datenmengen hantieren muss. Ist also doch durchaus brauchbar.