Zum Inhalt springen

SQL Tipp #001 – Data Profiling

    Eine typische Tätigkeit im Rahmen der fachlichen Konzeption ist auch die Systemanalyse – auch wenn viele Autoren oder Experten anderer Meinung sind und eher eine strikte Trennung zwischen Business Analyse und System Analyse für sinnvoll erachten. Meiner Meinung nach macht es keinen Sinn, eine scharfe Trennlinie zu ziehen. Bereits in der Phase der Anforderungsanalyse und der entsprechenden Dokumentation (Fachkonzept) ist es äußerst hilfreich und angebracht in Datenvorräte „hineinzuschauen“, um bereits zu einem sehr frühen Zeitpunkt die Machbarkeit zu prüfen und gegebenenfalls darauf zu reagieren. So werden keine „Luftschlösser“ gebaut und falsche oder etwa überzogene Erwartungshaltungen entstehen erst gar nicht. Natürlich sollte man in der Phase der Fachkonzeption die Aufwände für die Systemanalyse nicht ausufern lassen. Aber oftmals reicht ja bereits eine Stichprobe, um ein „Gefühl“ für die Daten zu bekommen. Ideal ist es, wenn die Quellsystemdaten bereits in einem relationalen Datenbank-System vorliegen, so dass mit Standard SQL Abfragen darauf zugegriffen werden kann. Vielleicht steht ja auch noch ein komfortabler SQL Editor zur Verfügung. In meinen Augen ein sehr wichtiges Werkzeug für jeden BI Business Analysten.

    Soweit so gut. Der Zugriff auf die Daten ist also gegeben. Jetzt geht es darum, sich schnell einen Überblick über die Daten zu verschaffen. Typische Fragen hierbei sind:

    • Welche Entitäten enthalten welche Datenstrukturen?
    • Was ist der fachlich eindeutige Schlüssel einer Entität (Business Key)
    • Wie stehen die Entitäten in Beziehung zueinander?
    • Welche Daten (Ausprägungen) enthalten die einzelnen Attribute (Tabellen-Spalten)?
    • Wie verteilen sich die einzelnen Ausprägungen prozentual? (Ausprägungskardinalität)
    • Welche Ausreißer gibt es?

    Das wissen um die Kardinalität ist bespielsweise sehr wichtig für eine korrekte und performante Datenmodellierung. Die obigen Fragen gehören zum Themengebiet des „Data Profiling„. Spezielle Tools hierfür sind auf dem Software-Markt erhältlich. Informatica bietet zum Beispiel sein Produkt „Data Analyst“ an, früher bekannt unter „Informatica Data Explorer“ (IDE). Es bietet sich an, den Fachbereich in den Profiling Prozess direkt miteinzubinden bzw. auch ihm das Profiling Werkzeug zur Verfügung zu stellen. Schließlich kennt er die Daten in der Regel am besten. Und falls nicht, so lernt er sie durch das Profiling sehr gut kennen. Leider ist ein dediziertes Profiling Tool nicht immer vorhanden – und an dieser Stelle kommt der heutige SQL Tipp zum Zug. Das nachfolgende SQL Skript liefert einen schnellen Überblick über die Daten – ähnlich wie ein professionelles Profiling Tool es tun würde.

    Nun zum Skript: Die Grundidee ist, das Data Dictionary der Datenbank zu verwenden, um sich das Profiling Skript dynamisch generieren zu lassen. D.h. die einzelnen Spalten einer Tabelle werden nicht manuell für jede zu untersuchende Tabelle angepasst, sondern aus dem Dictionary geholt.

    Schritt 1: Dynamischer Aufbau des Profiling SQLs. Eingabe Parameter sind Schema Name (DM_ALL) und der Tabellenname (td_d_par_org_mm) in Zeile 4

    -- dynamisch Query erzeugen
    WITH 
     tmptable (tmp_schema, tmp_table, tmp_count) AS 
     (VALUES('mySchema', 'myTable', (select count (*) from mySchema.myTable as tmp_count)))
    SELECT 
     -- dynamischer Aufbau eines SQL SELECT Statements
     'select sub.*, CEILING((sub.Anzahl / CAST('|| sub.tmp_count ||
     ' AS DECFLOAT)  * 100))  || ''%'' as Anteil from (select ' || 
     sub.COLNAME || ', count(COALESCE(' || sub.COLNAME || ',-9)) as Anzahl from '|| 
     sub.tmp_schema ||'.'|| sub.tmp_table ||' group by ' || sub.COLNAME || ') sub order by 2 desc;'
    FROM (
      SELECT 
       colname, tmp_schema, tmp_table, tmp_count
      FROM 
       syscat.columns, tmptable
      WHERE 
       tabschema = tmp_schema and tabname = tmp_table
      ORDER BY 
       colno  
    ) sub
    ;

    Schritt 2: Pro Tabellenspalte wird ein SQL generiert. Nachfolgend ist das  SQL Statement nur einer Spalte abgebildet (in dem Fall für die Spalte myColumn):

     -- so sieht die dynamisch generierte Query aus
    select 
     sub.*
    ,CEILING((sub.Anzahl / CAST(266 AS DECFLOAT)  * 100))  || '%' as Anteil 
    from (
     select 
      myColumn
     ,count(COALESCE(myColumn,-9)) as Anzahl 
     from 
      mySchema.myTable 
     group by 
      myColumn
     ) sub 
    order by 
     2 desc
    ;

    Schritt 3: Kopiert man nun die generierten SQL in den Editor und führt diese wiederum aus, so erhält man für jede einzelne Spalte einer Tabelle ein Profiling wie im nachfolgenden Screenshot dargestellt.

    Das Skript wurde getestet mit IBM DB2 v9.7

    Schlagwörter: