SQL: Ergebnismenge in Kreuztabelle (Cube) darstellen

Aus DBWiki
Wechseln zu: Navigation, Suche

Zurück zur Übersicht



Viele SQL-Dialekte haben für diesen Zweck eigene Implementierungen.


Es soll z.B. eine Liste von Produkten mit Farbausprägung gezählt und ihre Summen ausgegeben werden.

Lösung für Jet-SQL

Hinweis für Access-Anwender
Um die folgenden Abfragen selbst testen zu können, muss die Tabelle der Tabelle dual vorhanden sein.


Diese Abfrage vw_produkt dient uns als Ausgangsbasis.

SELECT 'A' AS produkt, 'rot' AS farbe FROM dual
UNION  ALL
SELECT 'B', 'rot' FROM dual
UNION  ALL
SELECT 'B', 'grün' FROM dual
UNION  ALL
SELECT 'B', 'blau' FROM dual
UNION  ALL
SELECT 'A', 'gelb' FROM dual
UNION  ALL
SELECT 'B', 'gelb' FROM dual
UNION  ALL
SELECT 'A', 'gelb' FROM dual
UNION  ALL
SELECT 'B', 'schwarz' FROM dual
UNION  ALL
SELECT 'C', 'grün' FROM dual
UNION  ALL
SELECT 'B', 'blau' FROM dual
UNION  ALL
SELECT 'B', 'blau' FROM dual
UNION  ALL
SELECT 'C', 'schwarz' FROM dual
UNION  ALL
SELECT 'C', 'blau' FROM dual

Hauptabfrage

TRANSFORM CLng( Nz( Count( * ), 0 ) ) AS x
SELECT v.Produkt,
       CLng( Nz( Count( * ), 0 ) ) AS Total
FROM   vw_produkt
GROUP  BY Produkt
PIVOT  farbe IN ( 'Rot', 'Grün', 'Blau', 'Gelb', 'Schwarz' )

Anmerkung Die Spalte Total muss an die richtige Position gezogen werden, damit sie auch dort später noch verweilt. Ab Version 2007 kann über das Start-Band oben optional eine Summen-Darstellung eingeblendet werden. Die darzustellenden Funktionen muss man einmalig selbst über Dropdown-Felder auswählen.

Lösung für PostgreSQL

SELECT produkt AS "Produkt",
       COALESCE( SUM( anzahl ) FILTER ( WHERE farbe = 'rot'     ), 0 ) AS "Rot",
       COALESCE( SUM( anzahl ) FILTER ( WHERE farbe = 'grün'    ), 0 ) AS "Grün",
       COALESCE( SUM( anzahl ) FILTER ( WHERE farbe = 'blau'    ), 0 ) AS "Gelb",
       COALESCE( SUM( anzahl ) FILTER ( WHERE farbe = 'gelb'    ), 0 ) AS "Blau",
       COALESCE( SUM( anzahl ) FILTER ( WHERE farbe = 'schwarz' ), 0 ) AS "Schwarz",
       COALESCE( SUM( anzahl ) FILTER ( WHERE farbe = 'Total'   ), 0 ) AS "Total"
FROM   ( SELECT COALESCE( produkt, 'Total' ) AS produkt,
                COALESCE( farbe, 'Total' ) AS farbe,
                COUNT ( * ) AS anzahl
         FROM   vw_produkt
         GROUP  BY CUBE ( produkt, farbe ) ) AS v
GROUP  BY produkt
ORDER  BY CASE WHEN produkt = 'Total' THEN 1 ELSE 0 END, produkt

Dieser DBFiddle zeigt diese Umsetzung.

Beide Abfragen sollten diese Darstellung hervorbringen:

Produkt Rot Grün Blau Gelb Schwarz Total
A 1 0 0 2 0 3
B 1 1 3 1 1 7
C 0 1 1 0 1 3
Total 2 2 4 3 2 13



Zurück zur Übersicht