Deutsch   |   English
   
 digg.com  del.icio.us 

Crosstab & Tabellen

Crosstab oder Pivotisieren von Tabellen

Manchmal ist es notwendig eine Kreuz- oder Pivottabelle mit Hilfe von SQL zu generieren. Warum? Zum Beispiel

  • Sie nutzen eine Reporting-Anwendung, die diese Funktionalität nicht unterstützt.
  • Sie nutzen eine historisch gewachsene Anwendung, die Sie nicht anpassen können.
  • Sie wollen bereits formatierte Daten ausgeben, z.B. in eine Textdatei.

Lassen Sie uns eine typische Situation betrachten, in dem Sie eine Pivotabelle erzeugen wollen. Als Basis dient uns eine View BEST_BUYER, die 3 umsatzstärksten Kunden pro Monat anzeigt:

CUST       ORDER_MO ORDER_SUM RANK 
---------- -------- --------- -----
Young      OCT-2008     20.50     1
Black      MAY-2009     21.17     1
Jones      OCT-2009     76.40     1
Adams      OCT-2009     63.21     2
Brown      OCT-2009     42.62     3
Green      NOV-2009     43.61     1
Adams      NOV-2009     40.05     2
Jones      NOV-2009     31.89     3
 

Allerdings ist es ein wenig schwierig, die Daten zu lesen und zu vergleichen, oder ein Diagramm zu erstellen, so dass Sie an diesem Punkt über eine Pivottabelle nachdenken, in der Monate Titel jeder Zeilen darstellen. Kundennamen werden in die Spalten "1", "2" und "3"anhand des Umsatzes des jeweiligen Monats platziert.

SELECT
   order_month
   , MAX(CASE WHEN cust_rank = 1 THEN cust ELSE NULL END) "1"
   , MAX(CASE WHEN cust_rank = 2 THEN cust ELSE NULL END) "2"
   , MAX(CASE WHEN cust_rank = 3 THEN cust ELSE NULL END) "3"
FROM best_buyer
GROUP BY order_month
;
ORDER_MO 1          2          3         
-------- ---------- ---------- ----------
OCT-2009 Jones      Adams      Brown     
OCT-2008 Young                           
NOV-2009 Green      Adams      Jones     
MAY-2009 Black                           
 

Crosstab mit Hilfe eines Skripts erstellen

Unsere Query liefert bereits das erwünschte Ergebnis. Allerdings erfordert diese Art von Queries viel Schreibarbeit, insbesondere wenn mehr als 3 Spalten im Spiel sind: man muss alle Werte kennen und sie einzeln für die Spaltenberechnung und -benennung einfügen.

Hier kann Skripting eine Abhilfe schaffen. Im folgenden werden wir ein Skript schreiben, dass eine beliebige Tabelle oder View anhand bestimmter Einstellungen erstellt.

Im ersten Schritt erstellen wir einen Skriptrumpf:

  1. CREATE OR REPLACE SCRIPT "GET_PIVOT"(objectname,col_select,col_pivot,col_aggregate,aggregate_function) RETURNS TABLE AS
  2. /*
  3.     objectname:         a selectable table or view
  4.     col_select:         column for first column in result table
  5.                         for this column row values are displayed  
  6.     col_pivot:          column that is transformed into columns
  7.                         for this column column values are displayed  
  8.     col_aggregate:      name of column or an appropriate expression for aggregate  
  9.     aggregate_function: the aggregate function to use for the pivot  
  10. */
  11. return
  12. /

Zunächst holen wir uns Werte für die Spaltennamen unserer Pivot-Tabelle. Diese Werte entnehmen wir der Spalte COL_PIVOT der Originaltabelle OBJECTNAME:

  1. -- get values will be used as column caption
  2. local collist = query([[select distinct ::col_p as val from ::obj order by ::col_p]], {obj = objectname, col_p = col_pivot} )
  3.  

Nun haben wir alle nötigen Werte, die wir in der Selectliste verwenden sollen in einem Dictionary COLLIST. Jetzt können wir die endgültige Query zusammensetzen. Wir benötigen zusätzlich noch einen Spaltennamen (COL_SELECT) für die erste Spalte der Pivottabelle: in unserem Beispiel handelt es sich hierbei um einen Bestellmonat.

  1. local querytext = [[select ::col_s]]
  2. -- iterate through column captions
  3. for i=1, #collist do
  4.     querytext = querytext..
  5. -- aggregate values of the col_aggregate column if the value the corresponding col_pivot contains the current caption
  6.         [[, ]]..aggregate_function..
  7.         [[(CASE WHEN ::col_p = ']]..collist[i].VAL..
  8.         [[' THEN ::col_a ELSE NULL END) AS ]]
  9.         -- use current caption as an alias, quote it to preserve case sensitivity
  10.         ..quote(collist[i].VAL)
  11. end
  12. querytext = querytext..[[ from ::obj
  13. group by ::col_s order by ::col_s]]
  14.  

Wir nutzen hier noch 2 Parameter: eine AGGREGATE_FUNCTION für maximale Flexibilität bei der Berechnung von Pivot-Werten und einen Spaltennamen COL_A, die diese Werte enthält. Dieser Parameter kann auch ein Ausdruck sein.

Nun können wir unsere zusammengesetzte Query aufrufen und das Ergebnis zurückgeben. Bitte beachten Sie, das Ergebnis des Skripts kann nicht in weiteren Anfragen verarbeitet werden.

  1. return  query(querytext, {obj = objectname, col_s = col_select, col_p = col_pivot, col_a = col_aggregate})
  2.  

Das komplette Skript können Sie hier herunterladen. Um das mit Hilfe von plain SQL erzieltes Ergebnis zu erreichen, reicht es aus, das Skript mit folgenden Parametern aufzurufen:

  1. EXECUTE SCRIPT get_pivot('BEST_BUYER', 'ORDER_MONTH', 'CUST_RANK', 'CUST', 'MAX');
  2.  

Da das Skript vollständig parametrisiert ist, können wir es verwenden, um den monatlichen Umsatz unserer besten Kunden zu errechnen:

  1. EXECUTE SCRIPT get_pivot('BEST_BUYER', 'ORDER_MONTH', 'CUST', 'ORDER_SUM', 'SUM');
  2.  
  1. ORDER_MO Adams    Black    Brown    Green    Jones    Young  
  2. -------- -------- -------- -------- -------- -------- --------
  3. MAY-2009             21.17                                    
  4. NOV-2009    40.05                      43.61    31.89        
  5. OCT-2008                                                 20.50
  6. OCT-2009    63.21             42.62             76.40        
  7.  
Sie kommen nicht weiter?
Referenzen
  • AHOOLY
  • COOP
  • „Mit EXASolution sind wir für zukünftiges Datenwachstum bestens gerüstet. Dadurch, dass wir jetzt Geodaten verarbeiten, sprich die Dimension des Raumbezugs mit auswerten können, bieten wir unseren Kunden ganz neue Analysemöglichkeiten und noch umfassendere Marktübersichten. Wir sind sehr zufrieden mit der neuen Lösung, können flexibel auf zukünftige Anforderungen reagieren und trotzdem unsere Total Cost of Ownership reduzieren, da der so gewählte BI-Stack unsere Vision eines „Lean-BI“ in vollem Umfang unsterstützt.“

    Guido Niermann, IT-Leiter, Dataforce GmbH

    Dataforce
  • "Durch die Einbindung von EXASOL können wir unseren Kunden ein ganz neues Erlebnis bezüglich der explorativen Datenanalyse bieten… Neben der Technologie waren wir vor allem mit der Pre-Sales Beratung und dem Support während der Integration äußerst zufrieden."

     Martin Heink
    Geschäftsführer und Inhaber, econda GmbH 

    Econda
  • "Entscheidend für die IMS Health war insbesondere, dass wir uns durch einen sehr schnell aufgesetzten Proof of Concept von der Leistungsfähigkeit von EXASolution direkt überzeugen konnten."

     Michael Kempke
    Director Data Collection Global Operations, IMS Health GmbH & Co. OHG

    IMS
  • "Mit der innovativen Datenbank von EXASOL können wir komplexe Berechnungen genauer und umfangreicher durchführen. Das gibt uns einen signifikanten Technologievorsprung gegenüber der Konkurrenz."

     Tobias Kiessling
    CTO, intelliAd 

    Intelliad
  • "Die durchgängig hohe Leistung und die Möglichkeit, Echtzeitanalysen fahren zu können, waren für uns ausschlaggebend bei der Wahl von EXASolution."

     Tobias Kroha, Geschäftsführer der für das m-pathy-Projekt verantwortlichen seto GmbH

    m-pathy
  • Media Control
  • Olympus
  • "Wir haben uns für EXASolution entschieden, da die Hochleistungsdatenbank mit den zu erwartenden großen Datenmengen sehr gut umgehen kann und optimale Flexibilität bietet."

     Dr. Michael Röbbecke
    (ehem.) Geschäftsführer, RatePAY 

    RatePAY
  • "Mit EXASolution können wir unsere Geschäftsprozesse deutlich optimieren." 

     Gerhard Zapf
    Projektleiter, Semikron 

    Semikron
  • "Ein zuverlässiger und schneller Support, eine bessere Kundenbetreuung sowie eine bewiesene Fachkompetenz…"

     David Hodge
    IT Director, Sony Music Entertainment Germany 

    Sony Music
  • SOQUERO
  • SponsorPay
  • Stayfriends
  • "Die Datenbank von EXASOL ist Technik made in Germany, auf die wir uns langfristig verlassen können. Da sie bei steigendem Datenvolumen selbstständig skaliert und auch physisch beliebig erweitert werden kann, wächst unsere Datenbank mit unserem Unternehmen, und wir können auch in Zukunft flexibel und schnell auf neue Anforderungen reagieren."

     Heinrich Zetlmayer
    Geschäftsführer, Turtle Entertainment 

    Turtle Entertainment
  • United Internet Dialog
  • "Mit EXASolution haben wir eine Lösung erworben, die unsere hohen Leistungsansprüche komplexer Analysen bei steigenden Datenmengen für unsere Kunden optimal erfüllt." 

     Christian Sauer
    Geschäftsführer, Webtrekk GmbH 

    Webtrekk
  • "Wir haben uns nach einem ausgiebigen Benchmark-Test für die Lösung von EXASOL entschieden. Die hohe Performance des Systems, das Preis-/Leistungs-Verhältnis und der Service haben uns vollauf überzeugt"

    Dr. Ulrich Fricke
    Leiter Business Intelligence, XING AG 

    Xing
  • "Neben Wirtschaftlichkeit, Geschwindigkeit und hoher Leistungsfähigkeit war Flexibilität eines der entscheidenden Kriterien bei der Wahl unserer Datenbank… Die neue Datenbank bietet uns diese Skalierbarkeit bei reduzierten Total Cost of Ownership. So können wir auch in Zukunft immer die optimale Analyseleistung für unsere Kunden erbringen…"

     Sebastian Hoop
    Head of Operations, xplosion interactive gmbh 

    Xplosion
  • Zalando