Summe in SQL ohne redundante Werte

gamma_matrices

Cadet 4th Year
Registriert
Sep. 2018
Beiträge
121
Hallo zusammen,

ich versuche ganze Zeit die Summe der Werte einer Spalte zu bilden OHNE redundante Einträge, aber trotz distinct werden alle Attributwerte addiert.
SQL:
select distinct v.id, sum(v.price) as summe, t.datum
from table_1 v join table_2 t on
v.id = t.id
where t.datum >= '...' and t.datum < '...'
group by v.id, t.datum

Was mache ich hier den verkehrt oder habt ihr evt. Tips / Vorschläge?
Danke schon mal im Voraus!
 
Der Distinct läuft erst auf das Ergebnis deines restlichen Selects. Soweit ich verstehe, willst du das genau nicht.

Ohne es exakt zu verstehen (zum Eindenken fehlen mir Beispieldaten der Tabellen), wirst du mit HAVING oder einer Subquery arbeiten müssen.
 
  • Gefällt mir
Reaktionen: Murray B. und madmax2010
Zwar keine Lösung zu deiner Frage aber warum bekommst du überhaupt redundante Einträge? Eigentlich sollte eine DB keine Redundanz haben Stichwort Normalisierung. Ich würde also nicht nach einer Lösung der Symptome schauen sondern nach einer Lösung des größeren Problems der Redundanz.
 
  • Gefällt mir
Reaktionen: Murray B., konkretor und madmax2010
Ich möchte gerne, dass nur Werte innerhalb eines bestimmten Intervalls summiert werden, die nur einmal vorkommen.
Mit Redundanz ist hierbei nicht streng gemeint, dass die Normalisierung hier verletzt ist, sondern, dass ich sich voneinander unterscheidende Werte summiert haben möchte.
 
Je nach verwendetem Dialekt kann man was mit einer Subquery machen oder mit Lag/Lead und Case.

Ich bin allerdings gerade zu müde um da Details zu recherchieren... Falls morgen noch Bedarf besteht, könnte ich mal was hacken.

Achja, der verwendete Dialekt wäre in dem Zusammenhang hilfreich.

Und je nach Server ist "distinct" ein echter Performancekiller...
 
"aber trotz distinct werden alle Attributwerte addiert."

Das liegt daran, dass zuerst die Werte addiert werden und danach Distinct ausgeführt wird.

Das kann man aber recht einfach anpassen, indem man eine Subquery verwendet, die stattdessen das Distinct enthält.
 
  • Gefällt mir
Reaktionen: Murray B. und mental.dIseASe
Hmmhh... überlege ganze Zeit wie ich das in der Konstellation des vorliegenden Querys bewerkstelligen könnte? Übrigens, musste ich beim SQL eine kleine Ergänzung beim Where hinzufügen, so dass korrekt wie folgt aussieht:
SQL:
select distinct v.id, sum(v.price) as summe, t.datum
from table_1 v join table_2 t on
v.id = t.id
where v.vnr = '...' and t.datum >= '...' and t.datum < '...'
group by v.id, t.datum

Man müsste ja jetzt geeignet eine Subquery beim Where ansetzen?🤔
 
@gamma_matrices : Kannst du bitte - wie schon mehrfach darum gebeten wurde - Beispieldaten liefern? Es ist mühselig, aus deinem Query, der ja offenbar falsche Ergebnisse liefert, deine Datenstruktur rauszuinterpretieren.
 
  • Gefällt mir
Reaktionen: Murray B.
Ok, als Beispiel hätten wir zwei Tabellen Tarif T und Vertrag V.

V hat folgende Attribute:
VertragID (pk)
VertragsNr (pk)
BeginnDatum
EndeDatum
Name

T:
TarifID (pk)
VertragID (fk)
Tarifart
Zahlung (hier: alias Preis)
Gueltigkeitsdatum (hier: alias Datum)

Hoffe, es ist so passend!
 
Danke. Und wie soll das Ergebnis aussehen?
Sprich: nach welchen Spalten soll gruppiert werden, und wie lautet die Bedingung für die Summe?

Und, noch wichtiger: was ist der Verwendungszweck des Resultats? Wenn man den kennt, dann ist der Weg zur Lösung meistens klarer.
 
Ich benötige die Summe der sich unterscheidenden Zahlungsbeträge für ein bestimmtes ganzes Jahr (zb von 2019) von einer bestimmten VertragsNr. Gruppiert sollte das nach Gueltigkeitsdatum, welches sich wiederum auf das Intervall 2019-01-01 bis 2019-12-31 beziehen sollte.
 
Okay, ich versuche es mal anhand eines fiktiven Beispiels in meine Worte zu fassen:
Eine bestimmte Vertragsnummer hat 12 Zahlungen im Jahr 2019, jeweils am 1. eines Monats.
Januar bis März je 10 Euro, ab April 20 Euro.
Du möchtest als Ergebnis "30 Euro" sehen und die Vertragsnummer.
Und welche Datumswerte? Und wie sollen die zusammengefasst werden? In einer Zelle, oder in mehreren Spalten?

Ich frage mich allerdings nach dem Zweck der Berechnung, das klingt sehr abstrakt und wenig praxisbezogen.
 
Murray B. schrieb:
Okay, ich versuche es mal anhand eines fiktiven Beispiels in meine Worte zu fassen:
Eine bestimmte Vertragsnummer hat 12 Zahlungen im Jahr 2019, jeweils am 1. eines Monats.
Januar bis März je 10 Euro, ab April 20 Euro.
Du möchtest als Ergebnis "30 Euro" sehen und die Vertragsnummer.
Und welche Datumswerte? Und wie sollen die zusammengefasst werden? In einer Zelle, oder in mehreren Spalten?
So könnte man das zusammenfassen. Ich möchte gerne nur sich unterscheidende Beträge summieren.
Datumswerte sind in einer Spalte aufgelistet, nur es gibt dort auch mehrere gleiche Einträge wie zB 10 Euro am 01.01.2019 existiert mehrmals! Habe mir gedacht, dass das Atribut Gueltigkeitsdatum evt. als Vektor vorhanden ist?

PS: Sorry, ich möchte gerne, die Beträge summieren, die sich von Datum her unterscheiden!
 
gamma_matrices schrieb:
Ich möchte gerne nur sich unterscheidende Beträge summieren.

gamma_matrices schrieb:
PS: Sorry, ich möchte gerne, die Beträge summieren, die sich von Datum her unterscheiden!
Diese beiden Aussagen unterscheiden sich komplett.

Bitte erstelle eine kleine Beispieltabelle mit den Eingangsdaten und die dazu gewünschte Ergebnistabelle. Ansonsten kommen wir hier nicht weiter.
 
Sorry, ich muss mich korrigieren, ich benötige Summe aller Beträge, die sich eindeutig zeitlich innerhalb eines Intervalls differenzieren.

Wenn ich zB SQL mit DISTINCT darauf loslasse, bekomme ich zB folgendes Ergebnis:

ZahlungDatum
15001.01.2019
13001.04.2019
10001.09.2019

Habe jetzt die Spalte mit VertragsNr weggelassen, da diese sowieso als Bedingung bei WHERE auftaucht.

Ohne DISTINCT:

ZahlungDatum
15001.01.2019
15001.01.2019
15001.01.2019
.....
13001.04.2019
13001.04.2019
......
10001.09.2019
......

So bekomme ich mehrere Einträge mit demselben Datum.

Und wenn ich jetzt auf DISTINCT mit SUM(Zahlung) reagiere, dann bekomme ich nicht als Ergebnis 150 + 130 + 100 = 380, sondern es werden alle Einträge addiert und das möchte ich gerne vermeiden.
 
Zuletzt bearbeitet:
gamma_matrices schrieb:
ich benötige Summe aller Beträge, die sich eindeutig zeitlich innerhalb eines Intervalls differenzieren.
Den Satz verstehe ich nicht.

Bitte unbedingt ein paar Beispieldaten mit dem gewünschten Ergebnis liefern. Ansonsten bin ich hier raus. Danke.
Ergänzung ()

gamma_matrices schrieb:
So bekomme ich mehrere Einträge mit demselben Datum.
OK, jetzt scheine ich die Problematik verstanden zu haben.

Die Datenstruktur ist offensichtlich sehr schlecht. Bitte an den Ersteller der Tabelle bzw. der Business-Logik herantreten, da muss vermutlich einiges anders strukturiert bzw. programmiert werden. Duplikate haben in einer Datenbank nichts verloren!

Als spontane Abhilfe eine Subquery mit GROUP BY machen und auf diesem Zwischenergebnis dann die Summen bilden.

SELECT
x.id, sum(x.preis)
FROM
( SELECT id, datum, preis
FROM tabelle
GROUP BY id, datum, preis)
x
GROUP BY x.id
 
Zuletzt bearbeitet von einem Moderator:
  • Gefällt mir
Reaktionen: gamma_matrices
Kannst du das bitte etwas konkretisieren, zB mit WHERE im SQL als Bezug auf eine VertragsNr und das Datumsintervall?
 
Das WHERE zum Datumsbereich gehört in die innere Query.
Das WHERE zur ID kann auch bei der äußeren Query stehen.
 
Wie ist den eigentlich das x in der Zeile über den letzten Group by zu interpretieren?
Ergänzung ()

SQL:
select v.id, sum(v.price) as summe
from (select distinct t.datum, v.price
      from table_1 v join table_2 t on
      v.id = t.id
      where t.datum >= '...' and t.datum < '...'
      group by t.datum, v.price)
where v.vnr = '...'   
group by v.id

Falls das so gemeint ist, bekomme ich leider Fehler in Zeile 1 als "ungültiger Bezeichner" für v.price?
 
Zuletzt bearbeitet:
Zurück
Oben