Commit 9e7c83e3 authored by Raphael Das Gupta's avatar Raphael Das Gupta
Browse files

remove MDX tutorial

parent ad064273
% MDX-Tutorial
% HSR Hochschule für Technik Rapperswil
% Data Analytics FS2019
# Benötigte Infrastruktur
Für diese Übung verwenden wir
Pentaho Business Intelligence (BI) Server 6.1 Community Edition (CE).
Sie können die Installation auf <https://pentaho-biserver.dev.ifs.hsr.ch> nutzen
oder den Server auf ihrem eigenen Gerät laufen lassen.
## (Optional:) Server selbst laufen lassen
Achtung:
Beide der folgenden Varianten um den Server selbst laufen zu lassen benötigen
einen Download von ca. 1 GiB
sowie mindestens 2 GiB (eher 4 bis 8 GiB) RAM.
Falls das Ihr Gerät zu stark auslastet,
greifen Sie stattdessen auf <https://pentaho-biserver.dev.ifs.hsr.ch> zurück.
### Variante 1: Server ohne Installation lokal starten (benötigt JRE)
Für diese Variante muss Java
(Runtime Environment genügt)
bereits installiert sein.
Laden Sie Pentaho BI Server CE (`biserver-ce-6.1.0.1-196.zip`) von
<https://sourceforge.net/projects/pentaho/files/Business%20Intelligence%20Server/6.1/>
herunter.
Entpacken Sie das ZIP-Archiv
und öffnen Sie ein Terminal im resultierenden Ordner.
(Ein Start direkt aus dem komprimierten Archiv funktioniert in der Regel nicht,
da mehrere Dateien aus dem Archiv zur Laufzeit benötigt werden.)
Um den Server zu starten,
führen sie den für Ihr System passenden `start-pentaho.*`-Skript aus.
Auf UNIX-artigen Systemen (Linux und Mac OS X):
./start-pentaho.sh
Auf Windows:
start-pentaho.bat
### Variante 2: Server in Linux-Docker-Container laufen lassen
docker run -p 8080:8080 -d wmarinho/pentaho-biserver:6.1
### Weitere Varianten
Pentaho BI Server CE kann auch systemweit installiert werden.
### Zugriff auf lokal laufenden Server (beide Varianten)
<http://localhost:8080>
## Login
Öffnen Sie die URL
(<https://pentaho-biserver.dev.ifs.hsr.ch> für die zur Verfügung gestellte Installation,
<http://localhost:8080> für einen lokal laufenden Server)
im Browser.
Klicken Sie auf "Login as an Evaluator" um die Login-Daten zu sehen.
(Mit den den "Go"-Buttons
können Sie direkt als der entsprechende Benutzer einloggen.)
Für diese Übung genügt der "Business User" (`Suzy`).
## MDX-Query-Editor für Steel-Wheels-Beispieldatensatz öffnen
Klicken Sie auf den "Create New"-Button
und wählen Sie "JPivot View".
Wählen Sie als Schema "SteelWheels"
und als Cube "SteelWheelsSales"
und klicken Sie "Ok".
Sie sehen eine Tabelle
mit Bestellungen.
Klicken Sie oben links
auf den "MDX"-Button,
um die MDX-Abfrage anzusehen,
die diese Ansicht erzeugt.
![Abbildung 1: JPivot MDX-Editor in Pentaho](img/JPivot-Screenshot.png)
Die einzelnen Elemente der Query werden später noch vorgestellt.
# Cube-Konzepte
## Dimensionen und Measures
Wenn wir Daten analysieren,
interessiert uns oft der Kontext der Daten,
z.B. "An welchem Ort haben wir am meisten verkauft?"
oder "Wer ist unser bester Verkäufer?"
Diesen Kontext nennen wir _Dimension_.
In den SteelWheels-Beispiel-Daten
wird jeder Bestellung
der geogr. Markt,
der Kunde,
das Produkt
und der Bestellungs-Status
zugewiesen,
sowie wann die Bestellung stattfand.
Natürlich ist auch gespeichert,
wieviel verkauft wurde
und zu welchem Preis.
Diese Werte nennen wir _Measures_.
Das Bild unten zeigt ein Beispiel-Datenschema
für ein Datawarehouse mit mehr Dimensionen.
Die gelb hinterlegte Tabelle hält alle Measures
und heisst _Faktentabelle_,
die blau hinterlegten beinhalten die Dimensionen
und heissen _Dimensionstabellen_.
![Abbildung 2: Star-Schema (DB-Schema für DW)](img/Star-Schema.png)
Die Werte in den Dimensionen werden
als _Member_ bezeichnet.
## Hierarchien & Levels
Die Member einer Dimension können zu Hierarchien zusammengefasst werden.
Ein Beispiel dafür ist das Bild unten:
![Abbildung 3: Beispiels-Cube mit Hierarchien](img/Cube-Hierarchy.png)
Die blauen Einträge oben gehören zur Dimension `Store`.
Sie beinhalten den Namen der Stadt,
in dem der Laden steht,
und den zusammengefassten Bundesstaat.
Die Dimension `Store` hat somit zwei Levels.
Die Verkaufswerte können für jeden Bundesstaat
zusammengefasst angezeigt werden.
Ist jemand an den einzelnen Orten in einem Bundesstaat interessiert,
kann er sich diese anzeigen lassen.
Das nennt man _Drill-Down_.
Eine Ebene höher zu gehen,
um sich die Daten wieder zusammengefasst anzeigen zu lassen,
nennt man _Drill-Up_.
Jedes Level hat einen Namen.
Die Namen werden zum Beispiel für die Funktion `Descendants` gebraucht,
die wir später vorstellen werden.
# MDX-Syntax
Die Namen der Members, Levels und Dimensionen
sind in diesem Tutorial mit eckigen Klammern umschlossen.
Es ist auch möglich,
die Namen ohne Klammern zu schreiben,
wenn der Name keinen Lehrschlag enthält.
Runde Klammern `()` umschliessen Tuples,
geschweifte Klammern `{}` umschliessen Sets.
## Tuples & Sets
Die Unterscheidung zwischen Tuples und Sets
ist in MDX wichtig:
Ein _Tuple_ entspricht einer "Koordinate" im Cube.
Es besteht aus einem Member pro Dimension im Cube.
Ein _Set_ besteht aus mehreren Tuples.
Viele Funktionen geben Sets zurück
oder erwarten Sets als Parameter,
zum Beispiel die Funktion `AVG`,
die ein Set erwartet,
um für die Tuples in diesem Set
den Durchschnittswert zu berechnen.
Ein Tuple muss nicht unbedingt
Member von allen Dimensionen enthalten.
Es ist auch möglich,
einige Member wegzulassen.
Die fehlenden Member werden dann
automatisch durch den Default Member
der jeweiligen Dimension erstetzt.
Meistens ist das der `All`-Member,
der die ganze Dimension zusammenfasst.
# MDX-Select Query
## Children & Members-Funktion
Gehen wir zurück zum SteelWheels-Beispiel.
Ändern Sie die MDX-Abfrage auf
```mdx
SELECT
{[Product].[All Products]} ON COLUMNS,
{[Measures].[Quantity]} ON ROWS
from [SteelWheelsSales]
```
und klicken sie "Apply".
Beachten Sie, dass `Measures` eine normale Dimension ist,
die wie alle anderen auch auf `ROWS`
oder `COLUMNS` gelegt werden kann.
Sie können auch mehrere Produktgruppen abfragen.
Geben Sie dazu folgendes an:
```mdx
SELECT
{[Product].[All Products].[Classic Cars],
[Product].[All Products].[Motorcycles]} ON COLUMNS,
{[Measures].[Quantity]} ON ROWS
from [SteelWheelsSales]
```
Damit Sie nicht alle Produktgruppen einzeln angeben müssen,
können Sie die Funktion `Children`
auf dem Member `[Product].[All Products]` aufrufen.
Das sieht dann so aus:
```mdx
SELECT
{[Product].[All Products].Children} ON COLUMNS,
{[Measures].[Quantity]} ON ROWS
from [SteelWheelsSales]
```
Die Funktion `Children`
gibt hier alle Members der unteren Hierarchy
für den Member `[Product].[All Products]` zurück.
Mit der `Members`-Funktion
werden alle Members einer Dimension zurückgegeben.
```mdx
SELECT
{[Product].[All Products]} ON COLUMNS,
{[Measures].Members} ON ROWS
from [SteelWheelsSales]
```
Hier werden alle existierenden `Measures`
für den `All`-Member von Product angezeigt.
## Descendants-Funktion
Mit der `Descendants`-Funktion können Sie
die Members auf einem bestimmten Level
für Ihre Dimension auflisten.
Das erste Argument ist der Name der Dimension
oder alternativ ein Member,
das zweite Argument ist der Name des Levels.
Im Query unten wird
für alle Monate im Jahr 2004
die Anzahl Verkäufe aufgelistet.
```mdx
SELECT {[Product].[All Products].Children} ON COLUMNS,
{Descendants([Time].[2004],[Months])} ON ROWS
FROM [SteelWheelsSales]
WHERE [Measures].[Sales]
```
## YTD-Funktion
Dank der Zeit-Dimension können Sie sich
die Verkaufszahlen bis zu einem bestimmten Zeitpunkt
aufzählen lassen:
```mdx
WITH MEMBER [Measures].[YTD] AS (
SUM(YTD(), [Measures].[Sales] )
)
SELECT
{[Measures].[YTD]} ON COLUMNS,
{[Time].[2004].Children} ON ROWS
FROM [SteelWheelsSales]
```
In diesem Query wird für jedes Quartal im Jahr 2004
der aufsummierte Profit angezeigt.
Mit `WITH` kann ein neuer berechneter Member
für diese Abfrage erzeugt werden.
## Current-Member, PrevMember, NextMember
Mit dieser Funktion sehen Sie,
welcher Member gerade aktiv ist,
und können einen zurück oder vorwärts springen.
```mdx
WITH MEMBER [Measures].[LastTimesSales] AS (
([Time].CurrentMember.PrevMember, [Measures].[Sales])
)
SELECT
{[Measures].[LastTimesSales], [Measures].[Sales]} ON COLUMNS,
{[Time].Members} ON ROWS
FROM [SteelWheelsSales]
```
Der Member `LastTimesSales` zeigt die Verkaufszahlen
der letzten Zeiteinheit an.
Diese kann ein Monat, ein Quartal oder ein Jahr sein.
Beachten Sie, dass auch Grenzen in der Hierarchie übersprungen werden,
zum Beispiel von Monat `Mar` auf Monat `Apr`.
## ParallelPeriod
Mit ParallelPeriod kann der Wert
von _vor_ einer oder mehrerer Zeiteinheiten geholt werden.
Die Funktion braucht
den Level,
die Anzahl Zeit-Einheiten
und den Member der als Ausgangspunkt dient.
```mdx
WITH MEMBER [Measures].[LastYearsSales] AS (
ParallelPeriod([Years], 1, [Time].CurrentMember), [Measures].[Sales]
)
SELECT
{[Measures].[LastYearsSales], [Measures].[Sales]} ON COLUMNS,
{[Time].Members} ON ROWS
FROM [SteelWheelsSales]
```
`LastYearsProfit` zeigt alle Verkaufszahlen
der entsprechenden Zeiteinheit des Vorjahres an,
egal von welchem Level.
## Crossjoin
Mit Crossjoin können Sie mehrere Sets kombinieren:
```mdx
SELECT
{[Measures].[Quantity]} ON COLUMNS,
Crossjoin(
[Markets].[All Markets].Children,
[Product].[All Products].Children
) ON ROWS
FROM [SteelWheelsSales]
```
Bei einer Abfrage wie zum Beispiel
```mdx
SELECT
{[Product].[All Products].Children} ON COLUMNS,
{[Measures].[Quantity]} ON ROWS
FROM [SteelWheelsSales]
WHERE ([Time].[2004].[QTR2])
```
sagt `WHERE` aus,
dass nur Werte aus dem 2. Quartal 2004
berücksichtigt werden sollen.
Auch mehrere Members können bei `WHERE` angegeben werden,
zum Beispiel
```mdx
SELECT
{[Product].[All Products].Children} ON COLUMNS,
{[Measures].[Quantity]} ON ROWS
FROM [SteelWheelsSales]
WHERE ([Time].[2005].[QTR2], [Order Status].[Shipped])
```
Hier werden die Daten zusätzlich
auf bereits ausgelieferte Bestellungen eingeschränkt.
Wichtig ist, dass
damit auch Funktionen wie `AVG` oder `SUM`
beeinflusst werden können.
version: '3.3'
services:
pentaho-biserver:
image: wmarinho/pentaho-biserver:6.1
networks:
- web
deploy:
labels:
- "traefik.enable=true"
- "traefik.docker.network=web"
- "traefik.frontend.rule=Host:pentaho-biserver.dev.ifs.hsr.ch"
- "traefik.port=8080"
restart_policy:
condition: on-failure
delay: 10s
max_attempts: 3
window: 600s
replicas: 1
placement:
constraints:
- node.role == manager
logging:
driver: "json-file"
options:
max-size: "200k"
max-file: "10"
networks:
web:
external:
name: web
{ pkgs ? import <nixpkgs> {} }:
pkgs.mkShell {
buildInputs = with pkgs; [
pandoc
texlive.combined.scheme-medium
];
}
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment