Język MDX(MultiDimensional Expressions)
Multidimensional Expressions (MDX) jest językiem zapytań używanym do wyszukiwania
danych wielowymiarowych w Microsoft SQL Server 2000/2005/2008/2012 Analysis Services (SSAS). MDX oparty jest na specyfikacji XMLA (XML for Analysis) rozszerzoną na specyfikę serwera SQL Server 2005 Analysis Services. Język MDX obejmuje identyfikatory, wartości, wyrażenia, funkcje i operatory wykonywane przez Analysis Services w celu udostępnienia obiektów (np. zbiór członów wymiaru) lub wartości skalarnych (np. liczby lub łańcucha znaków).
Zapytania i wyrażenia języka MDX używane są do:
• udostępnienia aplikacjom klienta danych zawartych w kostce;
• formatowania wyniku;
• wykonania zadań projektowych na kostce, takich jak: zdefiniowanie członów obliczanych
(calculated members), zdefiniowania zbiorów nazwanych (named sets), przypisania zakresów (scoped assignments), czy określenia kluczowych wskaźników wydajności (key performance indicators, KPIs).
• wykonania zadań administracyjnych takich jak określenie bezpieczeństwa dla wymiarów i
komórek.
Wyrażenie MDX SELECT ma następującą składnię:
[WITH <specifikacja_formuły>[, <specifikacja_formuły>
...]]
SELECT [<specifikacja_osi> [, <specifikacja_osi>...]]
FROM [<specyfikacja_kostki>]
[WHERE [<specifikacja_plastra>]]
MDX SELECT określa podzbiór wielowymiarowych danych wybierany z kostki.
Zapytanie MDX SELECT musi zawierać:
• od 1 do 128 osi (axes),
• człony wymiarów związane z poszczególnymi osiami,
• specyfikacja kostki określającej kontekst zapytania,
• wymiary lub człony, do których ograniczamy wybierane dane; definiują one
plaster (slice), który wycinamy z kostki;
• we frazie WITH możemy definiować człony obliczane i nazwane zbiory. Dla zobrazowania przykładów posługiwania się zapytaniami języka MDX będzie
analizowana następująca kostka: WypAut
Pomiary:
Wyrażenie SELECT - specyfikacja osi :
SELECT [<specifikacja_osi> [, <specifikacja_osi>...]]
Specyfikacja osi ma następującą składni ę :
<specifikacja_osi> ::= <zbiór_ciągów_członów> ON <nazwa_osi>
<nazwa_osi> ::= COLUMNS | ROWS | PAGES | SECTIONS |
CHAPTERS| AXIS(<indeks>)
Uwaga:
Nazwy pomiarów traktowane są jako człony wymiaru Measures.
A więc:
Measures = {Ilosc_wyp, Suma_oplat }.
Przestrzeń ma więc n+1 wymiarów:(Towar, Region, Okres, Measures)
Komórka (t, r, o, m) zawiera wartość pomiaru m.
Ze specyfikacji osi generowane są punkty w przestrzeni (n +1)-wymiarowej.
Wyrażenie SELECT … FROM :
Fraza FROM specyfikuje źródłowe zbiory komórek, na których wykonywane są operacje. W obecnej wersji języka MDX możliwe jest jedynie podawanie nazwy jednej istniejącej kostki:
<specifikacja_kostki> ::= <nazwa_kostki>
Wyrażenie SELECT … WHERE:
We frazie WHERE określane jest wyrażenie będąceswego rodzaju filtrem ograniczającym
zwracany zbiór komórek do pewnego plastra (ang. slicer).
Domyślnie przyjmuje się, że każdy wymiar, który nie został przyporządkowany do żadnej osi reprezentowany jest we frazie WHERE poprzez swój człon [All]. Jawne określenie innego członu powoduje, że tylko komórki budowane z wykorzystaniem tego członu należą do wynikowego zbioru komórek.
Składnia frazy WHERE jest następująca:
[WHERE [<specifikacja_plastra>]]
<specifikacja_plastra> ::= <punkt>
Na przykład wyrażenie
WHERE
([Miejsca].[Miasto].&[Kraków],[Measures].[Ilosc_wyp])
Ograniczy ono zbiór komórek do tych, które dotyczą wypożyczeń w mieście Kraków; umieszczenie pomiaru Ilosc_wyp we frazie WHERE oznacza, że tylko ten pomiar jest dla nas interesujący.
Wyrażenie WITH … SELECT:
We frazie WITH można definiować pomiary obliczane oraz przypisywać nazwy zbiorom.
Składnia tej frazy jest następująca:
WITH <specyfikacja_formuły> [, <specyfikacja_formuły> ...]
<specyfikacja_formuły> ::= <specyfikacja_członu> |
<specyfikacja_zbioru>
<specyfikacja_członu> ::= MEMBER
<rodzic_członu>.<nazwa_członu> AS `<wyrażenie>'
<specyfikacja_zbioru> ::= SET <nazwa_zbioru>
AS `<zbiór>'
Funkcje na wymiarach
Do definiowania zbiorów punktów możemy wykorzystywać szereg funkcji, m.in.:
• Crossjoin(X, Y) - tworzy iloczyn kartezjański zbiorów X i Y,
• Members - zwraca wszystkie człony z wymiaru, hierarchii lub poziomu, do których jest
stosowana: hierarchyExp.Members, levelExp.Members
• Children - zwraca zbiór członów będących dziećmi członu, do którego jest stosowana,
składnia memberExp.Children
Zapytanie 1
Jakie były ilości wypożyczeń Fiata w poszczególnych miastach, przy czasie wypożyczenia 2 dni ?
select {[Klienci].[Miasto].Members} on rows,
{[Measures].[Ilosc_Wyp] } on columns
from [WypAut]
where {( [Samochody].[Marka].[Fiat], [Czas].[Czas_Wyp].[2])};
Zapytanie 2
Podaj informacje o liczbie klientów, którzy wypożyczyli Forda lub Seata w Krakowie lub Warszawie
select {([Klienci].[Miasto].&[Kraków]),([Klienci].[Miasto].&[Warszawa])} on columns,
{([Towary].[Model].[Ford]), ([Towary].[Model].&[Seat])} on rows
from [WypAut]
where {[Measures].[LiczbaKlientow]};
Zapytanie 3
Podaj informację o ilości zakupionych samochodów przez kobiety i mężczyzn
select [Measures].[LiczbaTransakcji] on columns,
order (nonemptycrossjoin(
Plec.Plec.members,
Towary.[Model].[Model].Members
), [Measures].[LiczbaTransakcji],desc) on rows
from [Salon Cube];
Zapytanie 4
Podaj zysk i zysk procentowy (= zysk/koszt) dla poszczególnych marek.
Utwórz podsumowanie wartości tych miar za pomocą funkcji AGGREGATE i zinterpretuj wynik
with member Measures.[ZyskProc] as '[Measures].[Zysk]/[Measures].[Koszt]', format = '#.00%'
member Towary.[Marka].[Zagregowane] as 'aggregate([Towary].[Marka].[Marka].Members)'
select {[Measures].[Zysk], [Measures].[ZyskProc]} on columns,
{([Towary].[Marka].[Marka].Members), (Towary.[Marka].[Zagregowane])} on rows
from [Salon Cube];
Zapytanie 5
Podaj informacje o najlepiej sprzedającym się modelu samochodu wśród kobiet i wśród mężczyzn:
WITH MEMBER Measures.[MaxTrans] AS
'MAX({Towary.[Model].[Model].Members }, [Measures].[LiczbaTransakcji])'
select {(Measures.[MaxTrans])} on columns,
Filter(nonemptycrossjoin(
{Plec.Plec.members},
{Towary.[Model].[Model].Members}
),[Measures].[LiczbaTransakcji]=Measures.[MaxTrans]) on rows
from [Salon Cube];
Zapytanie 1
Jakie były zyski ze sprzedaży Fiata w poszczególnych miastach w 1999 roku?
SELECT {[KLIENCI].[MIASTO].MEMBERS} ON COLUMNS,
{MEASURES.ZYSK} ON ROWS
FROM [SALON]
WHERE {( TOWARY.[MARKA].[FIAT], [DNI].[1999])};
Zapytanie 2
Podaj informacje o liczbie klientów, którzy kupowali Punto lub Escorda w Sopocie lub Gnieźnie
SELECT {([KLIENCI].[MIASTO].&[SOPOT]),([KLIENCI].[MIASTO].&[GNIEZNO])} ON COLUMNS,
{([TOWARY].[MODEL].[PUNTO]), ([TOWARY].[MODEL].&[ESCORD])} ON ROWS
FROM [SALON]
WHERE {[Measures].[Id Kli Distinct Count]};
Zapytanie 3
Podaj informację o ilości zakupionych samochodów przez kobiety i mężczyzn
SELECT [Measures].[Sprzedaz Count] ON COLUMNS,
ORDER (NONEMPTYCROSSJOIN(
PLEC.PLEC.MEMBERS,
TOWARY.[MODEL].[MODEL].MEMBERS
), [Measures].[Sprzedaz Count],DESC) ON ROWS
FROM [SALON];
Zapytanie 4
Podaj zysk i zysk procentowy (= zysk/koszt) dla poszczególnych marek.
Utwórz podsumowanie wartości tych miar za pomocą funkcji AGGREGATE i zinterpretuj wynik
with member Measures.[ZyskProc] as '[Measures].[Zysk]/[Measures].[Koszt]', format = '#.00%'
member Towary.[Marka].[Zagregowane] as 'aggregate([Towary].[Marka].[Marka].Members)'
select {[Measures].[Zysk], [Measures].[ZyskProc]} on columns,
{([Towary].[Marka].[Marka].Members), (Towary.[Marka].[Zagregowane])} on rows
from [Salon];
Zapytanie 5
Podaj informacje o najlepiej sprzedającym się modelu samochodu wśród kobiet i wśród mężczyzn:
WITH MEMBER Measures.[MaxTrans] AS
'MAX({Towary.[Model].[Model].Members }, [Measures].[Sprzedaz Count])'
select {(Measures.[MaxTrans])} on columns,
Filter(nonemptycrossjoin(
{Plec.Plec.members},
{Towary.[Model].[Model].Members}
),[Measures].[Sprzedaz Count]=Measures.[MaxTrans]) on rows
from [Salon];