Gewichtete Aggregate: Weighted Average und Weighted Sum in SQL
AI generated
SELECT
JOIN
SQL · Gewichtete Aggregate · Weighted Average · Reporting
Gewichtete Aggregate
Weighted Average und Weighted Sum korrekt berechnen

Gewichtete Aggregate berücksichtigen, dass nicht jeder Wert in einem Report gleich viel zählen soll, etwa weil eine Bestellung mehr Artikel enthält als eine andere oder eine Klausur stärker gewichtet wird als ein Test. Dieser Artikel zeigt, warum ein einfaches AVG in solchen Fällen irreführende Durchschnittswerte liefert, und wie Weighted Average und Weighted Sum mit SUM(wert mal gewicht) geteilt durch SUM(gewicht) das korrekte Ergebnis berechnen.

13 Min. Lesezeit Weighted Average · Weighted Sum · SUM · NULLIF ANSI SQL · PostgreSQL · MySQL · SQL Server

1. Warum ein einfacher Durchschnitt manchmal die falsche Kennzahl ist

Gewichtete Aggregate lösen ein Problem, das bei einem naiven AVG regelmäßig übersehen wird: Nicht jeder Wert in einer Gruppe soll gleich stark in das Ergebnis eingehen. Ein typisches Beispiel ist der durchschnittliche Verkaufspreis eines Produkts über mehrere Bestellungen hinweg. Ein einfacher AVG(preis) behandelt jede Bestellzeile gleich, unabhängig davon, ob dabei ein Stück oder hundert Stück verkauft wurden, und verzerrt dadurch den tatsächlichen durchschnittlichen Verkaufspreis erheblich zugunsten kleiner Bestellungen.

Gewichtete Aggregate lösen dieses Problem, indem jeder Wert mit einem zugehörigen Gewicht multipliziert wird, bevor summiert und anschließend durch die Summe der Gewichte geteilt wird, statt durch die reine Anzahl der Zeilen. Bei der Preisberechnung wäre das Gewicht die verkaufte Menge, bei einer Notenberechnung der Prüfungsanteil, bei einer Portfolio-Rendite das investierte Kapital je Position. Das Prinzip bleibt in allen Fällen identisch, nur das fachliche Gewicht ändert sich je nach Anwendungsfall.

Dieser Artikel zeigt die allgemeine Formel für gewichtete Aggregate, arbeitet drei konkrete Anwendungsfälle durch, Durchschnittspreis, Notenberechnung und Portfolio-Rendite, und behandelt typische Fallstricke wie Division durch null und den korrekten Umgang mit negativen oder fehlenden Gewichten.

2. Die Formel: SUM(wert mal gewicht) geteilt durch SUM(gewicht)

Die allgemeine Formel für gewichtete Aggregate lautet SUM(wert mal gewicht) geteilt durch SUM(gewicht), wobei wert die zu mittelnde Größe ist und gewicht angibt, wie stark jede einzelne Zeile in das Gesamtergebnis eingehen soll. Diese Formel ist eine direkte Verallgemeinerung des einfachen arithmetischen Mittels: Setzt man jedes Gewicht auf den konstanten Wert eins, ergibt SUM(wert mal eins) geteilt durch SUM(eins) exakt denselben Wert wie AVG(wert), weil SUM(eins) über n Zeilen schlicht n ergibt.

Der entscheidende Unterschied zeigt sich, sobald die Gewichte tatsächlich unterschiedlich sind. Eine Zeile mit hohem Gewicht trägt proportional mehr zum Zähler UND zum Nenner bei als eine Zeile mit niedrigem Gewicht, wodurch das Endergebnis automatisch die tatsächliche fachliche Bedeutung jeder einzelnen Zeile widerspiegelt. Diese Formel für gewichtete Aggregate lässt sich in jeder SQL-Datenbank ohne Erweiterung direkt mit SUM und einer einfachen Division umsetzen, es ist keine spezielle WEIGHTED_AVG-Funktion nötig.


-- General formula for weighted aggregates
SELECT
    SUM(value * weight) / NULLIF(SUM(weight), 0) AS weighted_average
FROM measurements;

-- Compare with a plain, unweighted average
SELECT AVG(value) AS simple_average FROM measurements;
-- The two results diverge as soon as weights actually differ per row

3. Gewichteter Durchschnittspreis über mehrere Bestellungen

Der wohl häufigste praktische Anwendungsfall für gewichtete Aggregate im E-Commerce ist der durchschnittliche Verkaufspreis eines Produkts über mehrere Bestellungen hinweg, gewichtet nach der verkauften Menge. Ein einfacher AVG(einzelpreis) würde eine Bestellung über ein einzelnes Stück genauso stark gewichten wie eine Großbestellung über hundert Stück, obwohl letztere den tatsächlichen durchschnittlichen Verkaufspreis viel stärker beeinflusst.

Mit gewichteten Aggregaten wird die verkaufte Menge als Gewicht verwendet: SUM(einzelpreis mal menge) entspricht dem Gesamtumsatz des Produkts, SUM(menge) der Gesamtzahl verkaufter Einheiten. Der Quotient beider Summen liefert den tatsächlichen, mengengewichteten Durchschnittspreis, der exakt dem Gesamtumsatz geteilt durch die Gesamtmenge entspricht, statt einem Durchschnitt über einzelne Bestellzeilen, die je nach Bestellgröße völlig unterschiedliches Gewicht in der Realität haben.


-- Quantity-weighted average selling price per product
SELECT
    product_id,
    SUM(unit_price * quantity) / NULLIF(SUM(quantity), 0) AS weighted_avg_price,
    AVG(unit_price)                                       AS naive_avg_price
FROM order_items
GROUP BY product_id;

-- weighted_avg_price reflects the true revenue-per-unit,
-- naive_avg_price is skewed toward small orders

4. Gewichtete Notenberechnung mit unterschiedlichen Prüfungsanteilen

Ein klassisches Beispiel für gewichtete Aggregate außerhalb des E-Commerce ist die Notenberechnung in Bildungssystemen, bei der unterschiedliche Prüfungsformate unterschiedlich stark in die Gesamtnote einfließen sollen. Eine Abschlussklausur zählt typischerweise mehr als ein wöchentlicher Test, und ein einfacher AVG(note) würde diese fachlich gewollte Ungleichgewichtung ignorieren und jede Prüfung gleich behandeln, unabhängig von ihrer tatsächlichen Bedeutung für die Gesamtbewertung.

Mit gewichteten Aggregaten wird jeder Prüfung ein numerischer Gewichtungsfaktor zugeordnet, etwa eins für einen Test und drei für eine Abschlussklausur. SUM(note mal gewichtungsfaktor) geteilt durch SUM(gewichtungsfaktor) liefert dann die korrekt gewichtete Gesamtnote, bei der eine Abschlussklausur exakt dreimal so stark zählt wie ein einzelner Test, ohne dass die Berechnung dafür mehrfach dieselbe Notenzeile in der Tabelle duplizieren müsste.


-- Weighted grade average: final exams count 3x, quizzes count 1x
SELECT
    student_id,
    SUM(score * weight_factor) / NULLIF(SUM(weight_factor), 0) AS weighted_final_grade
FROM (
    SELECT student_id, score, 1 AS weight_factor FROM quiz_scores
    UNION ALL
    SELECT student_id, score, 3 AS weight_factor FROM exam_scores
) AS all_scores
GROUP BY student_id;

5. Gewichtete Portfolio-Rendite über mehrere Positionen

Im Finanzbereich sind gewichtete Aggregate die Standardtechnik zur Berechnung der Gesamtrendite eines Portfolios aus mehreren einzelnen Positionen. Eine Position mit hoher Investitionssumme soll die Gesamtrendite stärker beeinflussen als eine Position mit geringem eingesetztem Kapital, weshalb ein einfacher AVG(rendite) über alle Positionen hier fachlich grundlegend falsch wäre und die tatsächliche wirtschaftliche Situation eines Anlegers verzerrt darstellen würde.

Die korrekte Berechnung gewichtet jede einzelne Rendite mit dem investierten Kapital der jeweiligen Position: SUM(rendite mal investiertes_kapital) geteilt durch SUM(investiertes_kapital) liefert die kapitalgewichtete Gesamtrendite des Portfolios. Diese Kennzahl entspricht exakt dem Gesamtgewinn geteilt durch das Gesamtkapital, was ökonomisch die einzig sinnvolle Interpretation einer Portfolio-Rendite über mehrere unterschiedlich große Positionen ist.


-- Capital-weighted portfolio return across multiple positions
SELECT
    portfolio_id,
    SUM(return_pct * invested_capital) / NULLIF(SUM(invested_capital), 0) AS weighted_portfolio_return,
    AVG(return_pct) AS naive_avg_return
FROM portfolio_positions
GROUP BY portfolio_id;

-- weighted_portfolio_return reflects actual profit / total capital,
-- naive_avg_return treats a small and a large position as equally important

6. Gewichtete Aggregate kombiniert mit GROUP BY

Wie bei jeder anderen Aggregatfunktion lassen sich gewichtete Aggregate problemlos mit GROUP BY kombinieren, um die gewichtete Kennzahl nicht nur für die gesamte Tabelle, sondern für jede Gruppe einzeln zu berechnen. Ein Report, der den mengengewichteten Durchschnittspreis nicht nur global, sondern pro Produktkategorie oder pro Kalenderwoche ausweisen soll, erweitert die Formel einfach um eine passende GROUP-BY-Klausel, ohne dass sich an der eigentlichen SUM-Formel für gewichtete Aggregate etwas ändert.

Wichtig ist dabei, dass beide Summen, Zähler und Nenner, innerhalb derselben Gruppe berechnet werden, was bei GROUP BY automatisch gegeben ist, weil beide SUM-Aufrufe auf dieselbe Gruppierungsebene wirken. Ein häufiger Fehler entsteht dagegen, wenn Entwickler versuchen, gewichtete Aggregate über mehrere separate Abfragen mit unterschiedlicher Gruppierung zusammenzuführen, was leicht zu inkonsistenten Zähler-Nenner-Paaren führt, wenn die beiden Teilabfragen versehentlich unterschiedlich gefiltert werden.

7. Negative Gewichte und der Umgang mit Stornierungen

Eine Besonderheit bei gewichteten Aggregaten im Bestellkontext betrifft Stornierungen und Retouren, die häufig als negative Mengen in derselben Tabelle abgebildet werden. Eine stornierte Bestellzeile mit negativer Menge wirkt sich sowohl auf den Zähler SUM(preis mal menge) als auch auf den Nenner SUM(menge) aus, was in den meisten Fällen fachlich korrekt ist, weil eine Stornierung sowohl den Umsatz als auch die tatsächlich verkaufte Menge entsprechend reduzieren soll.

Problematisch wird es, wenn die Summe der Gewichte durch überwiegende Stornierungen negativ oder nahe null wird, weil die Division dann entweder ein vorzeichenverkehrtes oder ein extrem instabiles Ergebnis liefert. In solchen Fällen sollte vor der Division geprüft werden, ob der Nenner tatsächlich einen sinnvollen, positiven Wert ergibt, und gegebenenfalls eine explizite Fallunterscheidung für Gruppen mit überwiegend stornierten Mengen eingebaut werden, statt sich blind auf die Standardformel für gewichtete Aggregate zu verlassen.


-- Guarding weighted aggregates against a near-zero or negative weight sum
SELECT
    product_id,
    SUM(quantity)                                          AS net_quantity,
    CASE
        WHEN SUM(quantity) <= 0 THEN NULL  -- flag instead of a misleading number
        ELSE SUM(unit_price * quantity) / SUM(quantity)
    END AS weighted_avg_price_safe
FROM order_items  -- cancellations stored as negative quantity
GROUP BY product_id;

8. Fallstricke: Division durch null und NULL-Gewichte

Der häufigste technische Fallstrick bei gewichteten Aggregaten ist die Division durch null, die auftritt, sobald eine Gruppe ausschließlich aus Zeilen mit dem Gewicht null besteht oder gar keine Zeilen enthält. NULLIF(SUM(gewicht), 0) ist die Standardlösung, die den Nenner in NULL umwandelt, sobald er null ergibt, wodurch die Division zuverlässig NULL statt eines Laufzeitfehlers liefert, ganz analog zum allgemeinen NULLIF-Muster bei jeder Division in SQL.

Ein zweiter, subtilerer Fallstrick betrifft NULL-Werte im Gewicht selbst. Enthält die Gewichtsspalte NULL statt einer Zahl, wird die betroffene Zeile sowohl im Zähler als auch im Nenner faktisch ignoriert, weil sowohl die Multiplikation wert mal gewicht als auch das Gewicht selbst NULL werden und von SUM übersprungen werden. Das entspricht in vielen Fällen dem gewünschten Verhalten, sollte aber bewusst geprüft werden, weil eine fehlende Gewichtsangabe fachlich manchmal "Gewicht null" statt "unbekanntes Gewicht" bedeuten sollte, was mit COALESCE(gewicht, 0) statt dem impliziten NULL-Verhalten korrekt abgebildet wird.

9. Einfacher Durchschnitt vs. gewichteter Durchschnitt im Vergleich

Die folgende Übersicht stellt einfachen und gewichteten Durchschnitt anhand ihrer wichtigsten Eigenschaften gegenüber.

Eigenschaft Einfacher Durchschnitt (AVG) Gewichteter Durchschnitt
Gewichtung pro Zeile Jede Zeile zählt gleich Zeilen zählen nach fachlichem Gewicht
Formel SUM(wert) / COUNT(*) SUM(wert * gewicht) / SUM(gewicht)
Typische Anwendung Gleichwertige Einzelmessungen Preise, Noten, Portfolio-Renditen
Risiko bei falscher Wahl Verzerrung zugunsten kleiner Mengen Division durch null bei Gewicht 0

Wer eine Kennzahl berichtet, bei der einzelne Zeilen unterschiedlich stark ins Gewicht fallen sollten, etwa Mengen, Investitionssummen oder Gewichtungsfaktoren, sollte grundsätzlich gewichtete Aggregate statt eines einfachen AVG einsetzen, selbst wenn der Unterschied bei den vorliegenden Daten zunächst gering erscheint.

Mironsoft

Kennzahlen-Reviews und SQL-Reporting

Durchschnittspreis wirkt falsch? Vielleicht fehlt die Gewichtung.

Wir prüfen bestehende Reports auf fehlende Gewichtung und implementieren korrekte gewichtete Aggregate für Preise, Noten, Renditen und andere mengen- oder kapitalabhängige Kennzahlen.

Kennzahlen-Audit

Prüfung bestehender Durchschnittswerte auf fehlende, fachlich nötige Gewichtung

Report-Refactoring

Umstellung von AVG auf korrekte SUM-basierte gewichtete Aggregate

Fachliche Beratung

Gemeinsame Definition, welches Gewicht für eure Kennzahl fachlich korrekt ist

Gewichtete Aggregate sind kein exotisches Spezialwissen, sondern eine direkte, in jeder SQL-Datenbank verfügbare Erweiterung von SUM, die überall dort zwingend nötig ist, wo einzelne Zeilen fachlich unterschiedlich viel Gewicht tragen sollen.

10. Zusammenfassung

Gewichtete Aggregate berechnen Durchschnitte und Summen, bei denen jede Zeile entsprechend einem fachlichen Gewicht wie Menge, Prüfungsanteil oder investiertem Kapital unterschiedlich stark zählt. Die Formel SUM(wert mal gewicht) geteilt durch SUM(gewicht) verallgemeinert das einfache arithmetische Mittel und liefert bei gleichen Gewichten exakt dasselbe Ergebnis wie AVG.

Typische Anwendungsfälle sind mengengewichtete Durchschnittspreise, gewichtete Notenberechnungen und kapitalgewichtete Portfolio-Renditen. NULLIF schützt zuverlässig vor Division durch null, wenn die Summe der Gewichte in einer Gruppe null ergibt, und negative Gewichte bei Stornierungen erfordern besondere Aufmerksamkeit, wenn sie die Gewichtssumme insgesamt negativ werden lassen.

Gewichtete Aggregate: das Wichtigste auf einen Blick

Grundformel

SUM(wert * gewicht) / NULLIF(SUM(gewicht), 0), verallgemeinert das einfache arithmetische Mittel.

Typische Gewichte

Verkaufte Menge, Prüfungsanteil, investiertes Kapital, je nach fachlichem Anwendungsfall.

Division durch null

NULLIF(SUM(gewicht), 0) verhindert einen Fehler bei Gruppen ohne gültiges Gewicht.

Negative Gewichte

Stornierungen können die Gewichtssumme negativ werden lassen, Sonderfall gezielt behandeln.

11. FAQ: Gewichtete Aggregate

1Was sind gewichtete Aggregate?
Durchschnitte oder Summen, bei denen jede Zeile nach einem fachlichen Gewicht unterschiedlich stark zählt.
2Formel für gewichteten Durchschnitt?
SUM(wert * gewicht) / SUM(gewicht), bei Gewicht eins identisch zu AVG.
3Warum liefert AVG falsche Werte?
AVG behandelt jede Zeile gleich, unabhängig von fachlicher Bedeutung wie Menge oder Kapital.
4Gewicht bei Durchschnittspreis?
Die verkaufte Menge, SUM(preis*menge)/SUM(menge) liefert den Umsatz pro Einheit.
5Gewichtete Notenberechnung?
Gewichtungsfaktor pro Prüfung, etwa drei für Klausur, eins für Test.
6Division durch null vermeiden?
NULLIF(SUM(gewicht), 0) im Nenner verwenden.
7NULL-Gewichte?
Werden ignoriert, bei Bedarf mit COALESCE(gewicht, 0) explizit behandeln.
8Stornierungen behandeln?
Negative Mengen reduzieren Zähler und Nenner korrekt, Sonderfall bei überwiegender Stornierung prüfen.
9Portfolio-Rendite?
Gewichtung mit investiertem Kapital je Position statt einfachem Durchschnitt.
10Spezielle Funktion nötig?
Nein, SUM und Division genügen in jeder SQL-Datenbank.