Blog

Technik, Tipps, 

Lösungen & Projektberichten

SQL-Perle: mehrere GROUP BY Klausel in eine SQL-Abfrage

03. November 2013 geschrieben von 
Freigegeben in Tipps
SQL-Perle: mehrere GROUP BY Klausel in eine SQL-Abfrage Microsoft Clipart

Die Kategorisierung von Daten ist ein häufiges Ziel für Auswertungen und Datawarehouse-Abfragen.

Dabei werden oft GROUP BY Klausel und sogenannte Gruppen- oder Aggregatfunktionen verwendet, um die Wertemengen zu bearbeiten. Solche Funktionen sind COUNT, MIN, MAX, SUM, AVG usw.

Zusätzlich kann es sehr vorteilhaft sein, wenn eine einzelne Abfrage alle erwünschten Ergebnisse zurückliefert.

Z. B. dieser kann einfach in MS-Excel als externe SQL-Abfrage hinterlegt werden. Wertvolle Ad-hoc-Berichte können somit schnell und bequem implementiert werden, ohne dass weitere Kosten für die Entwicklung einer Benutzerschnittstelle nötig sind, um die Ergebnisse entsprechend aufzubereiten, zu sammeln und darzustellen.

Aber was ist, wenn die Ergebnisse für mehrere Kategorien gleichzeitig angezeigt werden sollen? Wie können mehrere GROUP BY Klausel in einer SQL-Abfrage implementiert werden?

Ein Praxisbeispiel:

Eine Datenbanktabelle beinhaltet einzelne Verkaufsabschlüsse - mit Datum und Gesamtwert der Einzelauftrag.

Um eine zukünftige Rabattaktion besser verfolgen zu können, möchte die Geschäftsführung die Verkaufsabschlüsse in 2 Wertebereiche kategorisieren und der Anzahl Abschlüsse sowie der Umsatzanteil pro Kategorie pro Kalenderwoche auflisten:

 Kalenderwoche: Anzahl
  Abschlüsse < €1000
Umsatzanteil %
 Abschlüsse< €1000
Anzahl
  Abschlüsse >= €1000
Umsatzanteil %
 Abschlüsse>= €1000
45 3 9,59  1 8,76
46 2 1,66  2 38,37
47 4 24,10  1 17,52

Die Ergebnisse für eine Kategorie sind per SQL relativ leicht zu ermitteln:

--Kategorie <€1000
SELECT 
  DATEPART(week, datum) AS Kalenderwoche,
  COUNT(*) AS "Anz. Abschlüsse <€1000",
  SUM(umsatz)*100/(SELECT SUM(umsatz) FROM DBAbschlusse) AS 'Umsatzanteil % Abschlüsse<€1000'
FROM DBAbschlusse WHERE Umsatz < 1000
GROUP BY DATEPART(week, datum);

--Kategorie >=€1000
SELECT 
  DATEPART(week, datum) AS Kalenderwoche,
  COUNT(*) AS "Anz. Abschlüsse >=€1000",
  SUM(umsatz)*100/(SELECT SUM(umsatz) FROM DBAbschlusse) AS 'Umsatzanteil % Abschlüsse>=€1000'
FROM DBAbschlusse WHERE Umsatz >= 1000
GROUP BY DATEPART(week, datum);

Aber wie können mehrere Wertebereiche in einer SQL-Abfrage vereint werden?

Hier ist eine Lösung:

SELECT 
  DATEPART(week, datum) AS Kalenderwoche, 
  SUM(anzkat1) AS "Anz. Abschlüsse <€1000", 
  SUM(umskat1)*100/(s.gesamtumsatz) AS "Umsatzanteil % Abschlüsse<€1000", 
  SUM(anzkat2) AS "Anz. Abschlüsse >=€1000", 
  SUM(umskat2)*100/(s.gesamtumsatz) AS "Umsatzanteil % Abschlüsse>=€1000"
FROM
(
  SELECT datum,
    CASE WHEN Umsatz < 1000 THEN 1 ELSE 0 END AS anzkat1,
    CASE WHEN Umsatz < 1000 THEN umsatz ELSE 0 END AS umskat1,
    CASE WHEN Umsatz >= 1000 THEN 1 ELSE 0 END AS anzkat2,
    CASE WHEN Umsatz >= 1000 THEN umsatz ELSE 0 END AS umskat2
  FROM DBAbschlusse
) t,
(
  SELECT SUM(umsatz) AS gesamtumsatz FROM DBAbschlusse
) s
GROUP BY gesamtumsatz, DATEPART(week, datum);

Die obere Syntax funktioniert für MS-SQL-Server 2008 und Pervasive SQL.

  • Für Oracle 11, muss DATEPART(week, Datum) durch TO_CHAR(Datum, 'IW') ersetzt werden.
  • Für PostgreSQL muss DATEPART(week, Datum) durch DATE_PART('week', datum) ersetzt werden.

 

Artikel bewerten
(0 Stimmen)