podstawy mdx - pelikant.imsi.pl mdx.pdf · 1 podstawy mdx select opis osi on columns, opis osi on...
TRANSCRIPT
1
Podstawy MDX
SELECTopis osi ON COLUMNS,opis osi ON ROWSFROM nazwa_kostki[WHERE opis_plastra]
Podstawowe zapytanie MDX ma strukturę podobną do zapytań SQL. Najprostsza postać zwraca dwuwymiarową kostkę:
Opis osi może być traktowany jako wybór członu dla osi. Jeżeli wymagany jest pojedynczy wymiar, przy użyciu takiego zapisu musi być zwrócone COLUMNS. Dla większej ilości wymaganych wymiarów nazwami osi byłyby PAGES(strony), CHAPTERS (rozdziały) oraz SECTIONS (sekcje).Jeśli chcemy użyć bardziej uniwersalnych określeń osi, możemy użyć konwencji: AXIS(index), gdzie index jest zakresem rozpoczynającym się od zera.W Management Studio dopuszczalne tylko dwie osie.
Struktura kostki [BiznesG]
Podstawy MDX
SELECT Measures.MEMBERS ON COLUMNS,[Nazwa kategorii].MEMBERS ON ROWSFROM [BiznesG]
Najprostsza postać opisu osi lub wyboru członów używa MEMBERS jako wymaganego wymiaru, łącznie ze wymiarem Measures:
Podstawy MDX
SELECT Measures.MEMBERS ON COLUMNS,{[Nazwa kategorii].[clocks],[Nazwa kategorii].[sampler] }ON ROWSFROM [BiznesG]
Jeżeli chcemy wyliczyć elementy wymiaru, mogą one być zwrócone jako pojedyncza oś (lista ograniczona {...} rozdzielona , :
2
Jan Feb Mar
Q1 Q2 Q3
Oct Nov Dec
Q4
2000
Q1 Q2 Q3 Q4
2001
All
Parents
Time.[2000].Parent Time.[2001].Parent
Time.[2000].[Q1].Parent
Time.[2000].[Q1].Parent.Parent
ANCESTOR(Time.[2000].[Q1], Time.[Year])
Jan Feb Mar
Q1 Q2 Q3
Oct Nov Dec
Q4
2000
Q1 Q2 Q3 Q4
2001
All
Time.[2000].FirstChild
Children
Time.[2000].Children
Jan Feb Mar
Q1 Q2 Q3
Oct Nov Dec
Q4
2000
Q1 Q2 Q3 Q4
2001
All
Descendants( Time.[2000], Quarter)
Descendants
Descendants( Time.[2000], Month)
Jan Feb Mar
Q1 Q2 Q3
Oct Nov Dec
Q4
2000
Q1 Q2 Q3 Q4
2001
All
Descendants(Time.[2000].[Jan], Month)
Descendants
3
Podstawy MDX
SELECT Measures.MEMBERS ON COLUMNS,{[KategoriaProduktuH].[Nazwa kategorii].[clocks].CHILDREN,[KategoriaProduktuH].[Nazwa kategorii].[sampler].CHILDREN }ON ROWSFROM [BiznesG]
Aby uzyskać miary dla członów składających się na te kategorie, zapytalibyśmy ich dzieci (CHILDREN):
Funkcja MEMBERS zwraca elementy wskazanego wymiaru lub poziomu wymiarów. Funkcja CHILDREN zwraca dzieci dla określonego członu wymiaru.Obie funkcje są używane przy formułowaniu wyrażeń, ale nie zapewniają możliwości rozwijania do niższych poziomów hierarchii.
Podstawy MDX
SELECT Measures.MEMBERS ON COLUMNS,{[KategoriaProduktuH].[Nazwa kategorii].[clocks],DESCENDANTS([KategoriaProduktuH].[Nazwa kategorii].[clocks], [Nazwa Towaru])}ON ROWSFROM [BiznesG]
Przy użyciu funkcji DESCENDANTS możliwe się staje zapytanie kostki o informacje na poziomie nazwa towaru dla wybranej kategorii
DESCENDANTS(człon, poziom [, flagi])
Wartość flagi może wynosić: SELF (domyślna wartość), BEFORE, AFTER lub BEFORE_AND_AFTER
Podstawy MDX
SELECT ADDCALCULATEDMEMBERS(Measures.MEMBERS) ON COLUMNS,{[KategoriaProduktuH].[Nazwa kategorii].[clocks],DESCENDANTS([KategoriaProduktuH].[Nazwa kategorii].[clocks],[Nazwa Towaru])}ON ROWSFROM [BiznesG]
Miary obliczane nie są dołączane, gdy pobierane są człony wymiarów. Ich uwzględnienie musi być jawnie narzucone, przez użycie funkcji ADDCALCULATEDMEMBERS:.
Podstawy MDXWybór miar do wyświetlenia
SELECT {MEASURES.wartosc, MEASURES.zysk} ON COLUMNS,{[KategoriaProduktuH].[Nazwa kategorii].[clocks],DESCENDANTS([KategoriaProduktuH].[Nazwa kategorii].[clocks], [Nazwa Towaru])}ON ROWSFROM [BiznesG]
4
Podstawy MDXZastosowanie krotki na wymiarach w celu wyświetlenia hierarchii
SELECT ADDCALCULATEDMEMBERS(Measures.MEMBERS) ON COLUMNS,{CROSSJOIN( [KategoriaTowaruG].[Nazwa kategorii].members, [KategoriaProduktuH].[Nazwa Towaru].members)}ON ROWSFROM [BiznesG]
Każd
apo
zycj
a z
jedn
ego
wym
iaru
z k
ażdą
z dr
ugie
go
CROSSJOIN nie może być zastosowany do dwa razy występującego tego samego wymiaru
Podstawy MDXZastosowanie krotki na wymiarach w celu wyświetlenia hierarchii
SELECT ADDCALCULATEDMEMBERS(Measures.MEMBERS) ON COLUMNS,{NONEMPTY (CROSSJOIN( [KategoriaTowaruG].[Nazwa kategorii].members, [KategoriaProduktuH].[Nazwa Towaru].members))}ON ROWSFROM [BiznesG]
W celu wyeliminowania niepowiązanych rekordówzastosować możemy operator NONEMPTY
Podstawy MDXZastosowanie krotki na wymiarach w celu wyświetlenia hierarchii
SELECT ADDCALCULATEDMEMBERS(Measures.MEMBERS) ON COLUMNS,{NONEMPTY (CROSSJOIN(FILTER ([KategoriaTowaruG].[Nazwa kategorii].members,[KategoriaTowaruG].[Nazwa kategorii]<>[KategoriaTowaruG].[Nazwa kategorii].[ALL]), [KategoriaProduktuH].[Nazwa Towaru].members))}ON ROWSFROM [BiznesG]
Wyeliminowanie elementu ALLreprezentującego wszystkie obiekty poziomu nadrzędnego osiągamy przez zastosowanie funkcji FILTER
Podstawy MDXNie zastosowanie krotki powoduje „spłaszczenie” wyświetlania
SELECT Measures.MEMBERS ON COLUMNS,{[KategoriaProduktuH].[Nazwa kategorii].members, [KategoriaProduktuH].[Nazwa Towaru].members}ON ROWSFROM [BiznesG]
Nazwy towarów dla kategorii CLOCKS
5
Podstawy MDX
SELECT[Nazwa Kategorii].MEMBERS ON COLUMNS,[LokalizacjaKlientaH].[Województwo].MEMBERS ON ROWSFROM [BiznesG]WHERE ([Measures].[wartosc])
Specyfikację plastra definiuje się przez klauzulę WHERE
Podstawy MDX
SELECT[Nazwa Kategorii].MEMBERS ON COLUMNS,[LokalizacjaKlientaH].[Województwo].MEMBERS ON ROWSFROM [BiznesG]WHERE ([Measures].[wartosc],[Data Faktury].[Rok].[2003])
Bardziej szczegółową definicję plastra można osiągnąć przez zdefiniowanie konkretnej wartości wymiaru
Nie można do definiowania plastra użyć wymiaru poprzednio wykorzystanego do definiowania kolumn lub wierszy
Podstawy MDXSELECT[KategoriaTowaruG].[Nazwa Kategorii].MEMBERS ON COLUMNS,[LokalizacjaKlientaH].[Województwo].MEMBERS ON ROWSFROM [BiznesG]WHERE ([Measures].[wartosc],[Towar G].[Nazwa Kategorii].[CLOCKS])
Definiowanie plastra z wykorzystaniem dwóch wymiarów zawierających ten sam poziom
Mało eleganckie ze względu na wartościNULL
Podstawy MDXSELECTNONEMPTY([KategoriaTowaruG].[Nazwa Kategorii].MEMBERS) ON COLUMNS,[LokalizacjaKlientaH].[Województwo].MEMBERS ON ROWSFROM [BiznesG]WHERE ([Measures].[wartosc],[Towar G].[Nazwa Kategorii].[CLOCKS]) Definiowanie plastra z
wykorzystaniem dwóchwymiarów zawierającychten sam poziom
Pominięcie wartościNULL przy użyciuNONEMPTY
6
Podstawy MDXSELECT[KategoriaTowaruG].[Nazwa Kategorii].[CLOCKS] ON COLUMNS,[LokalizacjaKlientaH].[Województwo].MEMBERS ON ROWSFROM [BiznesG]WHERE ([Measures].[wartosc])
Definiowanie plastra z wykorzystaniem jawnego wskazania na wartość w kolumnie
Podstawy MDX
WITH MEMBER Measures.ZyskProcentowy AS'([Measures].[Wartosc] - [Measures].[WartoscZakupu]) /[Measures].[WartoscZakupu]', FORMAT_STRING = '#.00%'SELECT[KategoriaTowaruG].[Nazwa Kategorii].MEMBERS ON COLUMNS,[LokalizacjaKlientaH].[Województwo].MEMBERS ON ROWSFROM [BiznesG]WHERE Measures.ZyskProcentowy
Możliwe jest wyznaczenie członów wyliczanych Ad hoc przy zastosowaniu klauzuli WITH
Podstawy MDX
WITH MEMBER Measures.ZyskProcentowy AS'([Measures].[zysk]) /[Measures].[WartoscZakupu]', FORMAT_STRING = '#.00%'SELECT[KategoriaTowaruG].[Nazwa Kategorii].MEMBERS ON COLUMNS,[LokalizacjaKlientaH].[Województwo].MEMBERS ON ROWSFROM [BiznesG]WHERE Measures.ZyskProcentowy
Możliwe jest wyznaczenie członów wyliczanych Ad hoc przy zastosowaniu klauzuli WITH oraz miary wyliczanej
Podstawy MDX
WITH MEMBER Measures.ZyskProcentowy AS([Measures].[Wartosc] - [Measures].[WartoscZakupu]) /[Measures].[WartoscZakupu], FORMAT_STRING = '0.000%'SELECTZyskProcentowy ON COLUMNS,[LokalizacjaKlientaH].[Województwo].MEMBERS ON ROWSFROM [BiznesG]
Możliwe jest wyznaczenie członów wyliczanych Ad hoc przy zastosowaniu klauzuli WITH
7
Podstawy MDX
WITH MEMBER Measures.ZyskProcentowy AS'([Measures].[zysk]) /[Measures].[WartoscZakupu]', FORMAT_STRING = '#.00%'SELECTADDCALCULATEDMEMBERS(MEASURES.MEMBERS) ON COLUMNS,[LokalizacjaKlientaH].[Województwo].MEMBERS ON ROWSFROM [BiznesG]
Możliwe jest wyznaczenie członów wyliczanych Ad hoc przy zastosowaniu klauzuli WITH i odczytanie ich przez ADDCALCULATEDMEMBERS
Podstawy MDX
Używając obliczanych członów możemy łatwo zdefiniować nowy wymiar CZASU służący do przedstawienia roku z rozbiciem na połowy :
WITH MEMBER Measures.ZyskProcentowy AS'([Measures].[zysk]) /[Measures].[WartoscZakupu]', FORMAT_STRING = '#.##%'MEMBER [Data Faktury].[Miesiac].PierwszaPolowa AS'[Miesiac].[1]+[Miesiac].[2]+[Miesiac].[3]+[Miesiac].[4]+[Miesiac].[5]+[Miesiac].[6]'MEMBER [Data Faktury].[Miesiac].DrugaPolowa AS'[Miesiac].[7]+[Miesiac].[8]+[Miesiac].[9]+[Miesiac].[10]+
[Miesiac].[11]+[Miesiac].[12]'SELECT{PierwszaPolowa, DrugaPolowa} ON columns,[KategoriaTowaruG].[Nazwa Kategorii].members on rowsFROM [BiznesG]WHERE Measures.ZyskProcentowy
Podstawy MDXWITH MEMBER Measures.ZyskProcentowy AS'([Measures].[zysk]) /[Measures].[WartoscZakupu]', FORMAT_STRING = '#.##%'MEMBER [Data Faktury].[Miesiac].PierwszaPolowa AS'[Miesiac].[1]+[Miesiac].[2]+[Miesiac].[3]+[Miesiac].[4]+[Miesiac].[5]+[Miesiac].[6]'MEMBER [Data Faktury].[Miesiac].DrugaPolowa AS'[Miesiac].[7]+[Miesiac].[8]+[Miesiac].[9]+[Miesiac].[10]+[Miesiac].[11]
+[Miesiac].[12]'SELECT{PierwszaPolowa, DrugaPolowa, [Data Faktury].Miesiac.MEMBERS} ON COLUMNS,[KategoriaTowaruG].[Nazwa Kategorii].MEMBERS on ROWSFROM [BiznesG]WHERE Measures.ZyskProcentowy
Podstawy MDXWITH MEMBER Measures.ZyskProcentowy AS'([Measures].[zysk]) /[Measures].[WartoscZakupu]', FORMAT_STRING = '#.##%‘,SOLVE_ORDER=1MEMBER [Data Faktury].[Miesiac].PierwszaPolowa AS'[Miesiac].[1]+[Miesiac].[2]+[Miesiac].[3]+[Miesiac].[4]+[Miesiac].[5]+[Miesiac].[6]'MEMBER [Data Faktury].[Miesiac].DrugaPolowa AS'[Miesiac].[7]+[Miesiac].[8]+[Miesiac].[9]+[Miesiac].[10]+[Miesiac].[11]
+[Miesiac].[12]'SELECT{PierwszaPolowa, DrugaPolowa, [Data Faktury].Miesiac.MEMBERS} ON COLUMNS,[KategoriaTowaruG].[Nazwa Kategorii].MEMBERS on ROWSFROM [BiznesG]WHERE Measures.ZyskProcentowy
Wymuszenie kolejnośćobliczania miar wyliczanych za pomocąSOLVE_ORDER=?
8
Podstawy MDXWITH MEMBER Measures.ZyskProcentowy AS'([Measures].[zysk]) /[Measures].[WartoscZakupu]', FORMAT_STRING = '#.##%',SOLVE_ORDER=1MEMBER [Data Faktury].[Kwartal].PierwszaPolowa AS'[Kwartal].[1]+[Kwartal].[2]'MEMBER [Data Faktury].[Kwartal].DrugaPolowa AS'[Kwartal].[3]+[Kwartal].[4]'SELECT{PierwszaPolowa, DrugaPolowa,[Data Faktury].Kwartal.MEMBERS} ON COLUMNS,[KategoriaTowaruG].[Nazwa Kategorii].MEMBERS ON ROWSFROM [BiznesG]WHERE Measures.ZyskProcentowy
Podobna realizacja ale dla wprowadzonej hierarchii Kwartal
Porównanie z poprzednim okresem
120Q1
105Dec100Nov80Oct
285Q470Sep60Aug55Jul
185Q390Jun45May65Apr
200Q2
50Mar40Feb30Jan
7902000
SalesMonQtrYear
DeltaSalesMonQtr
4590Jun-2045May1565Apr80200Q2
(Time.CurrentMember.PrevMember, Measures.Sales)
1. How did Sales this period compare with Sales in the previous period?
(DELTA) =
(Time.CurrentMember, Measures.Sales) -
Porównanie z równoległym okresem poprzedniego roku
8502001
120Q1
85Dec100Nov90Oct
275Q465Mar55Feb50Jan
170Q1
105Dec100Nov80Oct
285Q450Mar40Feb30Jan
7902000SalesMonQtrYear
9
8502001
120Q1
65Mar55Feb
2050Jan170Q1
50Mar40Feb30Jan
7902000DeltaSalesMonQtrYear
Porównanie z równoległym okresem poprzedniego roku
(Time.CurrentMember, Measures.Sales)-
(Time.CurrentMember.Lag(12), Measures.Sales)
(DELTA)=
(ParallelPeriod(Year,1,Time.CurrentMember), Measures.Sales)
Źle
Wyznaczanie sumy bieżącej od początku roku
120Q1
105Dec100Nov80Oct
285Q470Sep60Aug55Jul
185Q390Jun45May65Apr
200Q250Mar40Feb30Jan
7902000SalesMonQtrYear
Time.Mar,Measures.Sales
Time.Jan,Measures.Sales +Time.Feb,Measures.Sales +
3. What have Sales been since the beginning of the year?
12050Mar
7040Feb
3030Jan
120120Q1
7902000
YTDSalesMonQtrYear
ŹleSum(YTD(Time.CurrentMember), Sales)
Time.Mar,Measures.Sales
Time.Jan,Measures.Sales +Time.Feb,Measures.Sales +
3. What have Sales been since the beginning of the year?
=Sum(YTD(Time.CurrentMember), Sales)
12050Mar
7040Feb
3030Jan
120120Q1
7902000
YTDSalesMonQtrYear
10
Podstawy MDX
WITHSET [Kwartal1] AS GENERATE([Data Faktury].[DataFakturyH].[Rok].MEMBERS, {[Data Faktury].[DataFakturyH].CURRENTMEMBER.FIRSTCHILD})SELECT[Kwartal1] ON COLUMNS,[Towar G].[Nazwa Kategorii].MEMBERS ON ROWSFROM [BiznesG]WHERE ([Measures].[Zysk])
możemy wyświetlić zysk dla każdej kategorii towaru w każdym pierwszym kwartale (pierwszy potomek hierarchii) każdego roku:
Podstawy MDX
WITHSET [Kwartal1] AS GENERATE([Data Faktury].[DataFakturyH].[Rok].MEMBERS, {[Data Faktury].[DataFakturyH].CURRENTMEMBER.LASTCHILD})SELECT[Kwartal1] ON COLUMNS,[Towar G].[Nazwa Kategorii].MEMBERS ON ROWSFROM [BiznesG]WHERE ([Measures].[Zysk])
możemy wyświetlić zysk dla każdej kategorii towaru w każdym ostatnim kwartale (Ostatni potomek hierarchii – o ile istnieje) każdego roku:
Podstawy MDX
WITHSET [Kwartal1] AS GENERATE([Data Faktury].[DataFakturyH].[Rok].MEMBERS, {[Data Faktury].[DataFakturyH].CURRENTMEMBER.children(0)})SELECT[Kwartal1] ON COLUMNS,[Towar G].[Nazwa Kategorii].MEMBERS ON ROWSFROM [BiznesG]WHERE ([Measures].[Zysk])
możemy wyświetlić zysk dla każdej kategorii towaru w każdym pierwszym kwartale (pierwszy potomek hierarchii - numeracja od 0) każdego roku:
Podstawy MDX
WITHSET [Kwartal1] AS GENERATE([Data Faktury].[DataFakturyH].[Rok].MEMBERS, {[Data Faktury].[DataFakturyH].CURRENTMEMBER.children(3)})SELECT[Kwartal1] ON COLUMNS,[Towar G].[Nazwa Kategorii].MEMBERS ON ROWSFROM [BiznesG]WHERE ([Measures].[Zysk])
możemy wyświetlić zysk dla każdej kategorii towaru w każdym pierwszym kwartale (czwarty potomek hierarchii - numeracja od 0) każdego roku:
Gdy niezdefiniowano dla któregoś roku nie jest wyświetlany
11
Podstawy MDX
WITHMEMBER MEASURES.ZyskKategorii AS([KategoriaProduktuH].CURRENTMEMBER.PARENt, [Measures].[Zysk])MEMBER MEASURES.ZyskProcentowy AS([KategoriaProduktuH].CURRENTMEMBER, [Measures].[Zysk])/([KategoriaProduktuH].CURRENTMEMBER.PARENT, [Measures].[Zysk]),FORMAT_STRING = '0.00%'SELECT{Measures.ZyskKategorii, [Measures].[Zysk], MEASURES.ZyskProcentowy} ON COLUMNS,[KategoriaProduktuH].[Nazwa Towaru] ON ROWSFROM [BiznesG]
Wyznaczmy sprzedaż danej marki produktu jako udział procentowy wsprzedaży jego kategorii – czyli atrybutu, w odniesieniu do jego rodzica. Wyrażenie tworzące taki miarę obliczaną może zostać uzyskane przy użyciu właściwości CURRENTMEMBER oraz PARENT.
Podstawy MDX
WITHMEMBER MEASURES.ZyskKategorii AS([KategoriaProduktuH].CURRENTMEMBER.PARENT. PARENT, [Measures].[Zysk])MEMBER MEASURES.ZyskProcentowy AS([KategoriaProduktuH].CURRENTMEMBER, [Measures].[Zysk])/([KategoriaProduktuH].CURRENTMEMBER.PARENT.PARENT, [Measures].[Zysk]),FORMAT_STRING = '0.00%'SELECT{Measures.ZyskKategorii, [Measures].[Zysk], MEASURES.ZyskProcentowy} ON COLUMNS,[KategoriaProduktuH].[Nazwa Towaru] ON ROWSFROM [BiznesG]
PARENT może być używane wielokrotnie. W naszym przypadku przeniesie nas już na poziom ALL
Podstawy MDX
WITHMEMBER MEASURES.ZyskKategorii AS(ANCESTOR([KategoriaProduktuH].CURRENTMEMBER,[KategoriaProduktuH].[Nazwa Kategorii]), [Measures].[Zysk])MEMBER MEASURES.ZyskProcentowy AS([KategoriaProduktuH].currentmember, [Measures].[Zysk])/(ANCESTOR([KategoriaProduktuH].CURRENTMEMBER,[KategoriaProduktuH].[Nazwa Kategorii]), [Measures].[Zysk]),FORMAT_STRING = '0.00%'SELECT{MEASURES.ZyskKategorii,[Measures].[Zysk], MEASURES.ZyskProcentowy} ON COLUMNS,[KategoriaProduktuH].[nazwa towaru] ON ROWSFROM [BiznesG]
Wielokrotne użycie funkcji PARENT może być zastąpione przez obliczenie odpowiednich przodków członu CURRENTMEMBER przez funkcje ANCESTOR, zwracającą przodka na odpowiednim poziomie dla podanego członu. Konieczne jest użycie nazwy hierarchii:
Podstawy MDX
WITH SET [OproczZegarow] ASEXCEPT([KategoriaProduktuH].[Nazwa Kategorii].MEMBERS, [Towar G].[KategoriaProduktuH].[Nazwa Kategorii].[Clocks])MEMBER Measures.ProcentSprzedazy AS([KategoriaProduktuH].CURRENTMEMBER, [Measures].[Zysk]) /SUM([OproczZegarow], [Measures].[Zysk]),FORMAT_STRING = '#.00%'SELECT{[Measures].[Zysk], Measures.ProcentSprzedazy} ON COLUMNS,[OproczZegarow] ON ROWSFROM [BiznesG]
użycie nazwanych zbiorów i funkcji EXCEPT (odnajduje różnice pomiędzy dwoma zbiorami) umożliwia skonstruowanie wyrażenia, które pokaże procentową sprzedaż dla każdej grupy towarów w porównaniu do całości pomniejszonej o sprzedaż zegarów
12
Formatowanie warunkoweWITH SET Towary as [KategoriaProduktuH].[Nazwa Kategorii].MEMBERSMEMBER Measures.zakup AS [Measures].[Wartosc] , FORMAT_STRING = IIF(zakup>800,'#.00','{#.00)'),fore_color = IIF(zakup>800,RGB(255,0,0), RGB(255,255,0)),back_color = IIF(zakup>800,RGB(0,255,255), RGB(0,155,0)),FONT_FLAGS = IIF(zakup>800,MDFF_BOLD or MDFF_UNDERLINE ,MDFF_ITALIC or
MDFF_STRIKEOUT),FONT_NAME = IIF(zakup>800,ARIAL,Times),FONT_SIZE = IIF(zakup>800,16,10)SELECTTowary ON COLUMNS,[LokalizacjaKlientaH].[Województwo].MEMBERS ON ROWSFROM [BiznesG]WHERE Measures.ZakupCELL PROPERTIES VALUE, FORMATTED_VALUE, CELL_ORDINAL,FORMAT_STRING, FORE_COLOR, BACK_COLOR, FONT_FLAGS, FONT_NAME,
FONT_SIZE
Nie wszystko działa ?!!
Podstawy MDX
SELECT GENERATE([DataFakturyH].[Rok].MEMBERS, {[DataFakturyH].CURRENTMEMBER, [DataFakturyH].CURRENTMEMBER.CHILDREN})ON COLUMNS,[KategoriaProduktuH].[Nazwa Kategorii].members ON ROWSFROM [BiznesG]WHERE ([Measures].[Zysk])
Rozpatrzmy zapytanie mające zwracać na osi kolumn informacje o sprzedaży w każdym roku oraz odpowiadające im szczegóły kwartalne.
Podstawy MDX
SELECT GENERATE([DataFakturyH].[Rok].MEMBERS, {[DataFakturyH].CURRENTMEMBER,DESCENDANTS([DataFakturyH].CURRENTMEMBER, [Data Faktury].[DataFakturyH].[Kwartal])})ON COLUMNS,[KategoriaProduktuH].[Nazwa Kategorii].members ON ROWSFROM [BiznesG]WHERE ([Measures].[Zysk])
To samo ale z zastosowaniem DESCENDANTS
Podstawy MDX
SELECT GENERATE([DataFakturyH].[Rok].MEMBERS, {[DataFakturyH].CURRENTMEMBER,DESCENDANTS([DataFakturyH].CURRENTMEMBER, [Data Faktury].[DataFakturyH].[Miesiac])})ON COLUMNS,[KategoriaProduktuH].[Nazwa Kategorii].members ON ROWSFROM [BiznesG]WHERE ([Measures].[Zysk])
To samo ale z rozbiciem na miesiące
13
Podstawy MDX
WITHMEMBER Measures.[wzrost Zysku] AS([Measures].[Zysk]) - ([Measures].[Zysk],[DataFakturyH].PREVMEMBER),FORMAT_STRING = '###,###.00 ZŁ'SELECT{[Measures].[Zysk], Measures.[wzrost Zysku]} ON COLUMNS,{DESCENDANTS([DataFakturyH], [DataFakturyH].[miesiac])} ON ROWSFROM [BiznesG]
Pokazanie wzrostu w okresie czasu umożliwia funkcja PREVMEMBER. Jeżeli mielibyśmy wyświetlić zysk ze sprzedaży i przyrostową zmianę od poprzedniego członu czasu na poziomie kolejnych miesięcy
Podstawy MDX
WITHMEMBER Measures.[wzrost Zysku] AS([Measures].[Zysk]) - ([Measures].[Zysk],[DataFakturyH]. NEXTMEMBER),FORMAT_STRING = '###,###.00 ZŁ'SELECT{[Measures].[Zysk], Measures.[wzrost Zysku]} ON COLUMNS,{DESCENDANTS([DataFakturyH], [DataFakturyH].[miesiac])} ON ROWSFROM [BiznesG]
Użycie NEXTMEMBER w tym wyrażeniu pokazałoby sprzedaż dla każdego miesiąca zestawioną ze sprzedażami z poprzednich miesięcy.
Podstawy MDX
WITHMEMBER Measures.[wzrost Zysku] AS([Measures].[Zysk]) - ([Measures].[Zysk],[DataFakturyH]. LEAD)(-2)),FORMAT_STRING = '###,###.00 ZŁ'SELECT{[Measures].[Zysk], Measures.[wzrost Zysku]} ON COLUMNS,{DESCENDANTS([DataFakturyH], [DataFakturyH].[miesiac])} ON ROWSFROM [BiznesG]
Możemy również użyć funkcji LEAD, która zwraca człon oddalony w wymiarze o określoną liczbę pozycji od wskazanego członu.
Podstawy MDX
WITHMEMBER Measures.[wzrost Zysku] AS([Measures].[Zysk]) - (Measures.[Zysk], PARALLELPERIOD([DataFakturyH].[Kwartal])),FORMAT_STRING = '###,###.00 ZŁ'SELECT{[Measures].[Zysk], Measures.[wzrost Zysku]} ON COLUMNS,{DESCENDANTS([DataFakturyH], [DataFakturyH].[miesiac])} ON ROWSFROM [BiznesG]
PARALLELPERIOD pozwala na łatwe porównanie wzrostu ze wzrostem z tego samego przedziału czasu w poprzednim kwartale:
Pojawiają się błędy gdy nie zdefiniowno„równoległego” miesiąca.Miesiące w obrębie kwartału są wykrywane jako kolejne wystąpienia na liście, niezgodnie z kalendarzem
14
Podstawy MDX
WITHMEMBER Measures.[wzrost Zysku] AS([Measures].[Zysk]) - (Measures.[Zysk], OPENINGPERIOD([DataFakturyH].Miesiac,[DataFakturyH].CURRENTMEMBER.PARENT)),FORMAT_STRING = '###,###.00 ZŁ'SELECT{[Measures].[Zysk], Measures.[wzrost Zysku]} ON COLUMNS,{DESCENDANTS([DataFakturyH], [DataFakturyH].[miesiac])} ON ROWSFROM [BiznesG]
Można sprawdzić o ile wzrosła sprzedaż po pierwszym miesiącu sezonu. Używając kwartału do przedstawienia sezonu, można mierzyć różnicę w sprzedaży jednostek dla każdego miesiąca, porównując z miesiącem otwierającym kwartał:
OPENINGPERIOD(poziom, człon)CLOSINGINGPERIOD(poziom, człon)
Podstawy MDX
PERIODSTODATE([Time].[Year], [Time].CURRENTMEMBER)
Przy użyciu funkcji SUM i PERIODSTODATE można zdefiniować obliczany człon, który wyświetli informację year-to-date.. Miarą jest suma bieżąca na poziomie roku:
WITH MEMBER Measures.Zysk_YTD ASSUM(PERIODSTODATE([DataFakturyH].[Rok],[DataFakturyH].CURRENTMEMBER), [Measures].[Zysk]), FORMAT_STRING = '#.00'SELECT {[KategoriaTowaruG].[Nazwa Kategorii].MEMBERS} ON Columns,{DESCENDANTS([DataFakturyH], [DataFakturyH].miesiac)} ON rowsFROM [BiznesG]WHERE (Measures.Zysk_YTD)
Podstawy MDXW postaci skróconej można zastosować funkcję YTD()
WITH MEMBER Measures.Zysk_YTD ASSUM(YTD(), [Measures].[Zysk]), FORMAT_STRING = '#.00'SELECT {[KategoriaTowaruG].[Nazwa Kategorii].MEMBERS} ON Columns,{DESCENDANTS([DataFakturyH], [DataFakturyH].Miesiac)} ON rowsFROM [BiznesG]WHERE (Measures.Zysk_YTD)
Oprócz YTD() istnieją QTD(), MTD() i WTD().
Podstawy MDXPrzy użyciu funkcji SUM i PERIODSTODATE można zdefiniować obliczany człon, który wyświetli informację Quarter-to-date.. Miarą jest suma bieżąca na poziomie Kwartału:
WITH MEMBER Measures.Zysk_QTD ASSUM(PERIODSTODATE([DataFakturyH].[Kwartal],[DataFakturyH].CURRENTMEMBER), [Measures].[Zysk]), FORMAT_STRING = '#.00'SELECT {[KategoriaTowaruG].[Nazwa Kategorii].MEMBERS} ON Columns,{DESCENDANTS([DataFakturyH], [DataFakturyH].miesiac)} ON rowsFROM [BiznesG]WHERE (Measures.Zysk_QTD)
15
Podstawy MDXTo samo przy użyciu funkcji QTD:
WITH MEMBER Measures.Zysk_QTD ASSUM(QTD(), [Measures].[Zysk]), FORMAT_STRING = '#.00'SELECT {[KategoriaTowaruG].[Nazwa Kategorii].MEMBERS} ON Columns,[DataFakturyH].miesiac ON rowsFROM [BiznesG]WHERE (Measures.Zysk_QTD)
Podstawy MDXW wielu przypadkach kombinacja członów z różnych wymiarów jest zamkniętaw nawiasach. Kombinacja taka znana jest jako krotka (tuplet) i jest wykorzystywana do wyświetlenia wielu wymiarów na jednej osi.
SELECT[KategoriaTowaruG].[Nazwa Kategorii].MEMBERS ON COLUMNS,{CROSSJOIN( [Klienci G].[Województwo].MEMBERS, [Data Faktury].[Kwartal].MEMBERS)} ON ROWSFROM [BiznesG]WHERE ([Measures].[Zysk])
Podstawy MDXUsuwanie pustych członów z osi możemy osiągnąć przez zastosowanie klauzuli NON EMPTY,SELECT[KategoriaTowaruG].[Nazwa Kategorii].MEMBERS ON COLUMNS,NON EMPTY{CROSSJOIN( [Klienci G].[Województwo].MEMBERS, [Data Faktury].[Kwartal].MEMBERS)} ON ROWSFROM [BiznesG]WHERE ([Measures].[Zysk])
Przy takiej definicji krotki zapytanie bieżące i z poprzedniej strony zwracają to samo
Podstawy MDXDo filtrowania bardziej szczegółowego, MDX udostępnia funkcję FILTER. Zwraca ona zbiór, który jest wynikiem filtrowania na podstawieokreślonego warunku. FILTER (zbiór, warunek_wyszukiwania)
SELECT[KategoriaTowaruG].[Nazwa Kategorii].MEMBERS ON COLUMNS,FILTER({[LokalizacjaKlientaH].[Miasto].MEMBERS},([Measures].[Zysk], [DataFakturyH].[All])>500) ON ROWSFROM [BiznesG]WHERE ([Measures].[Zysk])
16
Podstawy MDXDo filtrowania bardziej szczegółowego, MDX udostępnia funkcję FILTER. Zwraca ona zbiór, który jest wynikiem filtrowania na podstawieokreślonego warunku. FILTER (zbiór, warunek_wyszukiwania)
SELECT[KategoriaTowaruG].[Nazwa Kategorii].MEMBERS ON COLUMNS,FILTER({[LokalizacjaKlientaH].[Miasto].MEMBERS},([Measures].[Zysk], [DataFakturyH].[All])>500) ON ROWSFROM [BiznesG]WHERE ([Measures].[Zysk], [DataFakturyH].[Rok].[2003])
Filtr dla zysku we wszystkich latach większego niż 500 ale wyświetlono zysk z roku 2003
Podstawy MDXJest sens stosowanie NON EMPTY – wyeliminowano PABIANICE
SELECT[KategoriaTowaruG].[Nazwa Kategorii].MEMBERS ON COLUMNS,NON EMPTY(FILTER({[LokalizacjaKlientaH].[Miasto].MEMBERS},([Measures].[Zysk], [DataFakturyH].[All])>500)) ON ROWSFROM [BiznesG]WHERE ([Measures].[Zysk], [DataFakturyH].[Rok].[2003])
Filtr dla zysku we wszystkich latach większego niż 500 ale wyświetlono zysk z roku 2003
Podstawy MDXZysk których z produktów spada poniżej średniej dla województwa ?????
WITHMEMBER [Measures].[ZyskProcentowy] AS([Measures].[Wartosc]-[Measures].[WartoscZakupu]) /([Measures].[WartoscZakupu]), FORMAT_STRING = '#.00%'SELECTNON EMPTY {[KategoriaTowaruG].[Nazwa Kategorii].MEMBERS} ON COLUMNS,FILTER({[LokalizacjaKlientaH].[Miasto].MEMBERS}, ([Measures].[ZyskProcentowy], [DataFakturyH].[All]) < ([Measures].[ZyskProcentowy], [DataFakturyH].[All],ANCESTOR([LokalizacjaKlientaH].CURRENTMEMBER, [LokalizacjaKlientaH].[Województwo]))) ON ROWSFROM [BiznesG]WHERE ([Measures].[ZyskProcentowy], [DataFakturyH].[All])
Podstawy MDXRozpatrzmy proste zapytanie o miary dla lokalizacji klientów (miasta):
SELECT [Measures].MEMBERS ON COLUMNS,[LokalizacjaKlientaH].[Miasto].MEMBERS ON ROWSFROM [BiznesG]
17
Podstawy MDXPierwszym wyświetlonym miastem jest Bydgoszcz etc... Naturalna kolejność nie jest zbyt widoczna ponieważ nie znamy członu z poziomu rodzica. Jeśli bylibyśmy zainteresowani miastami wylistowanymi między Kutno a Czersk musielibyśmy napisać:
SELECT [Measures].MEMBERS ON COLUMNS,[LokalizacjaKlientaH].[Miasto].[KUTNO]:[CZERSK] ON ROWSFROM [BiznesG]
Podstawy MDXSortowanie wyników
ORDER(zbiór, wyrażenie [, ASC | DESC | BASC | BDESC])
SELECT [Measures].MEMBERS ON COLUMNS,ORDER([LokalizacjaKlientaH].[Miasto].[KUTNO]:[CZERSK],[LokalizacjaKlientaH].CURRENTMEMBER.NAME, BASC) ON ROWSFROM [BiznesG]
Prefiks “B” wskazuje, że hierarchiczny porządek może zostać rozbity.
W przykładzie tym sortowanie odbyło się po właściwości Name. Zwraca on nazwę poziomu, wymiaru, członu, lub hierarchii. Istnieje podobna właściwość – UniqueNamezwracająca odpowiednią unikalną nazwę.
Podstawy MDXSortowanie wyników
ORDER(zbiór, wyrażenie [, ASC | DESC | BASC | BDESC])
SELECT [Measures].MEMBERS ON COLUMNS,ORDER([LokalizacjaKlientaH].[Miasto].[KUTNO]:[CZERSK],[LokalizacjaKlientaH].CURRENTMEMBER.NAME, ASC) ON ROWSFROM [BiznesG]
Brak prefiksu “B” wskazuje, że hierarchiczny porządek nie może zostać rozbity.
Podstawy MDXDość często bieżące sortowanie jest oparte o aktualną miarę.
SELECT [Measures].MEMBERS ON COLUMNS,ORDER([LokalizacjaKlientaH].[Miasto].MEMBERS,[Measures].[Wartosc], DESC) ON ROWSFROM [BiznesG]
Zapytamy o informacje sprzedaży w miastach, uporządkowaną wedługefektywności sprzedaży:
18
Podstawy MDXDość często bieżące sortowanie jest oparte o aktualną miarę.
SELECT [Measures].MEMBERS ON COLUMNS,ORDER([LokalizacjaKlientaH].[Miasto].MEMBERS,[Measures].[Wartosc], BDESC) ON ROWSFROM [BiznesG]
Zapytamy o informacje sprzedaży w miastach, uporządkowaną wedługefektywności sprzedaży:
Bez rozbicia wynikającego z hierarchii
Podstawy MDXHEAD funkcja zwracająca pierwszych n członów z podanego zbioru. Podobnie TAIL – zwraca n ostatnich członów z podanego zbioru.
SELECT [Measures].MEMBERS ON COLUMNS,HEAD(ORDER([LokalizacjaKlientaH].[Miasto].MEMBERS,[Measures].[Wartosc], BDESC), 10) ON ROWSFROM [BiznesG]
Ograniczmy zakres wyświetlanych miast do 10 najbardziej wydajnych:
Podstawy MDXTOPCOUNT zwraca ze zbioru n najlepszych na podstawie podanego wyrażeniawyników.
SELECT [Measures].MEMBERS ON COLUMNS,TOPCOUNT([LokalizacjaKlientaH].[Miasto].MEMBERS, 10,[Measures].[Wartosc]) ON ROWSFROM [BiznesG]
Poprzednie wyrażenie możemy zatem przepisać:
TOPCOUNT(zbiór, n, wyrażenie_numeryczne)
Podstawy MDXZapytanie MDX, które wyświetla górne 10 miast, w oparciu o ilość transakcji sprzedaży, oraz jak dużo sprzedały łącznie pozostałe miasta. Takie wyrażenie pokaże także inne zastosowanie funkcji SUM, nawiązujące do nazwanych zbiorów i obliczanych członów:
WITHSET TopTens ASTOPCOUNT([LokalizacjaKlientaH].[Miasto].MEMBERS, 10, [Measures].[Ilosc])MEMBER [LokalizacjaKlientaH].[Inne Miasta] AS ([LokalizacjaKlientaH].[All], Measures.CURRENTMEMBER) -SUM(TopTens, Measures.CURRENTMEMBER)SELECT [Measures].MEMBERS ON COLUMNS,{TopTens, [Inne Miasta]} ON ROWSFROM [BiznesG]
Istnieje również TOPPERCENT, TOPSUM
Oczywiście istnieje seria funkcji BOTTOM
19
Podstawy MDXWyświetlanie listy miast, których ilość transakcji sprzedaży obejmuje 50% całości sprzedaży:
SELECT [Measures].MEMBERS ON COLUMNS,TOPPERCENT({[Klienci G].[LokalizacjaKlientaH].[Miasto].MEMBERS}, 50,[Measures].[Ilosc]) ON ROWSFROM [BiznesG]
Podstawy MDXWyświetlanie listy 50% osób, których zarobki w roku 2004 były najwyższe
SELECT TOPPERCENT ([Osoby G].[Pracownik].[Pracownik].members, 50, ([Measures].[Brutto], [Data Zarobki].[Rok].[2004])) ON ROWS,{[Data Zarobki].[Rok].[2004]} ON COLUMNSFROM ZarobkiG
Podstawy MDXrozkład ilości sprzedaży dla typów sklepów:
SELECT [Nazwa Kategorii].MEMBERS ON COLUMNS,TOPPERCENT({[LokalizacjaKlientaH].[Miasto].MEMBERS}, 50,[Measures].[Ilosc]) ON ROWSFROM [BiznesG]WHERE [Measures].[Ilosc]
Podstawy MDXZastosowanie TOPSUM
WITH MEMBER[Data Faktury].[Rok].[2002 + 2003] AS ([Measures].[Wartosc], [Data Faktury].[Rok].[2002]) + ([Measures].[Wartosc], [Data Faktury].[Rok].[2003])SELECT{[Data Faktury].[Rok].[2002], [Data Faktury].[Rok].[2003] ,[Data Faktury].[Rok].[2002 + 2003]} ON COLUMNS,TOPSUM([Towar G].[Nazwa Towaru].[Nazwa Towaru].members, 10000, [Data Faktury].[Rok].[2002 + 2003]) ON ROWS FROM BiznesG WHERE [Measures].[Wartosc]
20
Podstawy MDXFunkcje statystyczne AVG, MEDIAN, MAX, MIN, VAR oraz STDDEV. Format jest jednakowy dla wszystkich:
WITHMEMBER [DataFakturyH].[SredniaSprzedaz] ASAVG(DESCENDANTS([DataFakturyH].[Rok], [DataFakturyH].[Miesiac]))MEMBER [DataFakturyH].[SredniaIlosc] AS COUNT(DESCENDANTS([DataFakturyH].[Rok], [DataFakturyH].[Miesiac]),EXCLUDEEMPTY)SELECT {[DataFakturyH].[Rok],[SredniaSprzedaz],[SredniaIlosc]} ON COLUMNS,[KategoriaTowaruG].[Nazwa Kategorii] ON ROWSFROM [BiznesG]WHERE [Measures].[Ilosc]
FUNKCJA(zbiór, wyrażenie_numeryczne)
Podstawy MDXFunkcje te, zwane “user-defined functions” (UDF) mogą przyjmować argumenty i zwracać wartości w składni MDX. UDF mogą być tworzone w dowolnym języku wspomagającym COM (Common Object Model), Na dodatek, MDX obsługuje wiele funkcji z biblioteki Microsoft Visual Basic for Applications (VBA) ExpressionServices. Biblioteka ta jest dołączona do OLAP Services i jest automatycznie rejestrowana.
SELECTMeasures.MEMBERS ON COLUMNS,FILTER({[LokalizacjaKlientaH].[Miasto].MEMBERS},VBA!INSTR(1, [Miasto].CURRENTMEMBER.Name, "KA")>0)ON ROWSFROM [BiznesG]
Możemy zapytać o miary dla miasta, gdzie wartość zawiera łańcuch “KA”:
Prefiks VBA nie jest potrzebny. Wskazuje jedynie pełnokwalifikowanepochodzenie funkcji.
Podstawy MDXJeśli zapytanie ma zwracać wzrost procentowy
WITHMEMBER Measures.[WzrostZysku] AS ([Measures].[Zysk]) /([Measures].[Zysk], [DataFakturyH].PREVMEMBER), FORMAT_STRING = '#.00%'SELECT{[Measures].[Zysk], [WzrostZysku] } ON COLUMNS,DESCENDANTS([DataFakturyH].[Rok], [DataFakturyH].[Miesiac]) ON ROWSFROM [BiznesG]
Problemem - pierwszy okres czasu powoduje dzielenie przez zero...
Podstawy MDX
WITHMEMBER Measures.[WzrostZysku] AS IIF( ISEMPTY([DataFakturyH].PREVMEMBER), 1, ([Measures].[Zysk]) /([Measures].[Zysk], [DataFakturyH].PREVMEMBER)), FORMAT_STRING = '#.00%'SELECT{[Measures].[Zysk], [WzrostZysku] } ON COLUMNS,DESCENDANTS([DataFakturyH].[Rok], [DataFakturyH].[Miesiac]) ON ROWSFROM [BiznesG]
Ten problem może zostać w omnięty przez użycie IIF i sprawdzenie istnienia pustej komórki:
21
Podstawy MDXTaka sama funkcjonalność może być osiągnięta przy użyciu funkcjiCOALESCEEMPTY, która przypisuje pustej wartości komórki liczbę lub łańcuch i go zwraca. W tym przypadku, pusta komórka z poprzedniego członu czasu, byłaby zastąpiona wartością bieżącym członem czasu:
WITHMEMBER Measures.[WzrostZysku] AS ([Measures].[Zysk]) /COALESCEEMPTY(([Measures].[Zysk], [DataFakturyH].PREVMEMBER),[Measures].[Zysk]), FORMAT_STRING = '#.00%'SELECT{[Measures].[Zysk], [WzrostZysku] } ON COLUMNS,DESCENDANTS([DataFakturyH].[Rok], [DataFakturyH].[Miesiac]) ON ROWSFROM [BiznesG]
Średnia dla miast dla wybranych województw za lata 2001 do 2004
WITHMEMBER [Measures].[lubelskie AVG] AS AVG({[Klienci G].[lubelskie].CHILDREN},[Measures].[Wartosc])MEMBER [Measures].[łódzkie AVG] AS AVG({[Klienci G].[łódzkie].CHILDREN},[Measures].[Wartosc])MEMBER [Measures].[pomorskie AVG] AS AVG({[Klienci G].[pomorskie].CHILDREN},[Measures].[Wartosc])SELECT{([Measures].[lubelskie AVG]), ([Measures].[łódzkie AVG]),([Measures].[pomorskie AVG])} ON COLUMNS,{([Data Faktury].[2001]:[2003])} ON ROWS FROM BiznesG
Średnia bieżąca - CENTRALNAWITH MEMBER Measures.SredniaBiezaca ASAVG({[Miesiac].CURRENTMEMBER, [Miesiac].PREVMEMBER, [Miesiac].NEXTMEMBER},[Measures].[Wartosc]), FORMAT_STRING = '#.00 zł'SELECT[KategoriaProduktuH].[Nazwa Kategorii].[THAN] ON COLUMNS,[DataFakturyH].[Miesiac].MEMBERS ON ROWSFROM [BiznesG]WHERE Measures.SredniaBiezaca
Średnia bieżąca - WSTECZNAWITH MEMBER Measures.SredniaBiezaca ASAVG({[Miesiac].CURRENTMEMBER, [Miesiac].PREVMEMBER, [Miesiac].PREVMEMBER.PREVMEMBER},[Measures].[Wartosc]), FORMAT_STRING = '#.00 zł'SELECT[KategoriaProduktuH].[Nazwa Kategorii].[THAN] ON COLUMNS,[DataFakturyH].[Miesiac].MEMBERS ON ROWSFROM [BiznesG]WHERE Measures.SredniaBiezaca
22
Średnia bieżąca – WSTECZNA Inna realizacja
WITH MEMBER Measures.SredniaBiezaca ASAVG({[Miesiac].CURRENTMEMBER.LAG(2):[Miesiac].CURRENTMEMBER},[Measures].[Wartosc]), FORMAT_STRING = '#.00 zł'SELECT[KategoriaProduktuH].[Nazwa Kategorii].[THAN] ON COLUMNS,[DataFakturyH].[Miesiac].MEMBERS ON ROWSFROM [BiznesG]WHERE Measures.SredniaBiezaca
Średnia bieżąca - PORÓWNANIEWITH MEMBER Measures.SredniaBiez ASAVG({[Miesiac].CURRENTMEMBER.LAG(2):[Miesiac].CURRENTMEMBER},[Measures].[Wartosc]), FORMAT_STRING = '#.00 zł'MEMBER Measures.SredniaBiezaca ASAvg({[Miesiac].CURRENTMEMBER,[Miesiac].PREVMEMBER, [Miesiac].NEXTMEMBER}, [Measures].[Wartosc]), FORMAT_STRING = '#.00 zł'SELECT{Wartosc, Measures.SredniaBiez, Measures.SredniaBiezaca} ON COLUMNS,
[Data Faktury].[DataFakturyH].[Miesiac].MEMBERS ON ROWSFROM [BiznesG]WHERE {[KategoriaProduktuH].[Nazwa Kategorii].[THAN]};
- z?
200,00 z?
400,00 z?
600,00 z?
800,00 z?
1 000,00 z?
1 200,00 z?
1 400,00 z?
1 600,00 z?
1 800,00 z?
1 3 5 7 9 11 13 15 17 19 21 23 25 27 29 31 33 35
WartoscSredniaBiezSredniaBiezaca
Średnia bieżąca - PORÓWNANIEWITH MEMBER Measures.SredniaBiez ASAVG({[Miesiac].CURRENTMEMBER.LAG(2):[Miesiac].CURRENTMEMBER},[Measures].[Wartosc]), FORMAT_STRING = '#.00 zł'MEMBER Measures.SredniaBiezaca ASAVG({[Miesiac].CURRENTMEMBER.LAG(5):[Miesiac].CURRENTMEMBER},[Measures].[Wartosc]), FORMAT_STRING = '#.00 zł'SELECT{Wartosc, Measures.SredniaBiez, Measures.SredniaBiezaca} ON COLUMNS,
[Data Faktury].[DataFakturyH].[Miesiac].MEMBERS ON ROWSFROM [BiznesG]WHERE {[KategoriaProduktuH].[Nazwa Kategorii].[THAN]};
- z?
200,00 z?
400,00 z?
600,00 z?
800,00 z?
1 000,00 z?
1 200,00 z?
1 400,00 z?
1 600,00 z?
1 800,00 z?
1 3 5 7 9 11 13 15 17 19 21 23 25 27 29 31 33 35
WartoscSredniaBiezSredniaBiezaca
Średnia bieżąca - PORÓWNANIEWITH MEMBER Measures.SredniaBiez ASAVG({[Miesiac].CURRENTMEMBER.LAG(-2):[Miesiac].CURRENTMEMBER},[Measures].[Wartosc]), FORMAT_STRING = '#.00 zł'MEMBER Measures.SredniaBiezaca ASAVG({[Miesiac].CURRENTMEMBER.LAG(2):[Miesiac].CURRENTMEMBER},[Measures].[Wartosc]), FORMAT_STRING = '#.00 zł'SELECT{Wartosc, Measures.SredniaBiez, Measures.SredniaBiezaca} ON COLUMNS,
[Data Faktury].[DataFakturyH].[Miesiac].MEMBERS ON ROWSFROM [BiznesG]WHERE {[KategoriaProduktuH].[Nazwa Kategorii].[THAN]};
- z?
200,00 z?
400,00 z?
600,00 z?
800,00 z?
1 000,00 z?
1 200,00 z?
1 400,00 z?
1 600,00 z?
1 800,00 z?
1 3 5 7 9 11 13 15 17 19 21 23 25 27 29 31 33 35
WartoscSredniaBiezSredniaBiezaca
23
Podstawy MDX
LITERATURA
•http://msdn.microsoft.com/library/en-us/olapdmad/agmdxbasics_4erb.asp•http://msdn.microsoft.com/library/en-us/olapdmad/agmdxbasics_6wag.asp•http://msdn.microsoft.com/library/en-us/olapdmad/agmdxadvanced_5ke0.asp•http://msdn.microsoft.com/library/en-us/olapdmad/agmdxadvanced_0woo.asp•http://msdn.microsoft.com/library/en-us/olapdmad/agmdxfunctintro_65iw.asp
CROSS JOIN na wymiarach definiowanych ad hoc
WITH SET czasr AS [DataFakturyH].[Rok].membersSET czasq AS [Data Faktury].[Kwartal].membersSELECT Measures.Wartosc ON COLUMNS ,CROSSJOIN(CZASR, FILTER(CZASQ, CZASQ.currentmember.value <> [Kwartal].[all]) ) ON ROWSFROM [BiznesG]
CROSS JOIN na wymiarach definiowanych ad hoc
WITH SET czasr AS [DataFakturyH].[Rok].membersSET czasq AS [Data Faktury].[Kwartal].membersSET czasm AS [Data Faktury].[Miesiac].membersSELECT Measures.Wartosc ON COLUMNS ,CROSSJOIN(CROSSJOIN(CZASR, FILTER(CZASQ, CZASQ.currentmember.value <> [Kwartal].[all]) ),FILTER(czasm, CZASm.currentmember.value <> [miesiac].[all])) ON ROWSFROM [BiznesG]
CROSS JOIN na wymiarach definiowanych ad hoc
WITH SET czasr AS [DataFakturyH].[Rok].membersSET czasq AS [Data Faktury].[Kwartal].membersSET czasm AS [Data Faktury].[Miesiac].membersSET czasd AS [Data Faktury].[Dzien].membersSELECT Measures.Wartosc ON COLUMNS ,CROSSJOIN(CROSSJOIN(CROSSJOIN(CZASR, FILTER(CZASQ, CZASQ.currentmember.value <> [Kwartal].[all]) ),FILTER(czasm, CZASm.currentmember.value <> [miesiac].[all])),FILTER(czasd, CZASd.currentmember.value <> [dzien].[all])) ON ROWSFROM [BiznesG]
24
CROSS JOIN na wymiarach definiowanych ad hoc (strasznie wolne)
WITH SET czasr AS [DataFakturyH].[Rok].membersSET czasq AS [Data Faktury].[Kwartal].membersSET czasm AS [Data Faktury].[Miesiac].membersSET czasd AS [Data Faktury].[Dzien].membersSET kategoria AS [KategoriaProduktuH].[Nazwa Kategorii].membersSET towar AS [Towar G].[Nazwa Towaru].membersSELECT nonempty(CROSSJOIN(kategoria,filter(towar,towar.currentmember.value<>[Nazwa Towaru].[all]))) ON columns ,nonempty(CROSSJOIN(CROSSJOIN(CROSSJOIN(CZASR, FILTER(CZASQ, CZASQ.currentmember.value <> [Kwartal].[all]) ),FILTER(czasm, CZASm.currentmember.value <> [miesiac].[all])),FILTER(czasd, CZASd.currentmember.value <> [dzien].[all]))) ON rowsFROM [BiznesG]where [Measures].[Wartosc]
CROSS JOIN na wymiarach definiowanych ad hoc (inna realizacja)WITH
SET czasr AS [DataFakturyH].[Rok].membersSET czasq AS [Data Faktury].[Kwartal].membersSET czasm AS [Data Faktury].[Miesiac].membersSET czasd AS [Data Faktury].[Dzien].membersSET kategoria AS [KategoriaProduktuH].[Nazwa Kategorii].membersSET towar AS [Towar G].[Nazwa Towaru].membersSET Towary AS nonempty(CROSSJOIN(kategoria,filter(towar,towar.currentmember.value<>[Nazwa Towaru].[all])))SET CZAS AS nonempty( CROSSJOIN( CROSSJOIN( CROSSJOIN( CZASR, FILTER(CZASQ, CZASQ.currentmember.value <> [Kwartal].[all]) ),FILTER(czasm, CZASm.currentmember.value <> [miesiac].[all])),FILTER(czasd, CZASd.currentmember.value <> [dzien].[all])))SELECT towary ON columns ,czas on rowsFROM [BiznesG]where [Measures].[Wartosc]
Podstawy MDX
WITHMEMBER [Time].[1997].[H1] AS '[Time].[1997].[Q1] + [Time].[1997].[Q2]'MEMBER [Time].[1997].[H2] AS '[Time].[1997].[Q3] + [Time].[1997].[Q4]'SELECT{[Time].[1997].[H1], [Time].[1997].[H2]} ON COLUMNS,[Store].[Store Name].MEMBERS ON ROWSFROM [Sales]WHERE (Measures.Profit)
Człony obliczane mogą być również zależne od członu istniejącego w tej samej hierarchii, tak jak w przykładzie:
Wzrost wynagrodzenia za okres od 2002 do 2004
WITH MEMBER[Measures].[Wzrost_wynag] As ([Data Zarobki].[Rok].Currentmember,[Measures].[Brutto])-([Data Zarobki].[Rok].PrevMember, [Measures].[Brutto])SELECT{([Measures].[Brutto]), ([Measures].[Wzrost_wynag])} ON COLUMNS,{[Data Zarobki].[Rok].[2002]:[Rok].[2004]} ON ROWSFROM ZarobkiG
25
Zestawy rekordów dwie realizacje tego samego
SELECT{[Data Faktury].[DataFakturyH].[Rok].members} ON COLUMNS,{[Towar G].[LokalizacjaProducentaH].[Województwo].[pomorskie].CHILDREN, [Towar G].[LokalizacjaProducentaH].[Województwo].[śląskie].CHILDREN} ON ROWS FROM BiznesG WHERE [Measures].[Wartosc]
SELECT{[Data Faktury].[DataFakturyH].[Rok].members} ON COLUMNS,{UNION([Towar G].[LokalizacjaProducentaH].[Województwo].[pomorskie].CHILDREN, [Towar G].[LokalizacjaProducentaH].[Województwo].[śląskie].CHILDREN)} ON ROWS FROM BiznesG WHERE [Measures].[Wartosc]
Podwójne filtrowanie i sortowanie wartość dla roku 2004 większa niż dla 2003
różnica wartości między 2003 a 2004 większa niż 50WITH MEMBER[Data Faktury].[Rok].[2004 - 2003] AS ([Measures].[Wartosc], [Data Faktury].[Rok].[2004]) –([Measures].[Wartosc], [Data Faktury].[Rok].[2003])SELECT{([Data Faktury].[Rok].[2003]),([Data Faktury].[Rok].[2004]),([Data Faktury].[Rok].[2004 - 2003])} ON COLUMNS,{ORDER(FILTER(FILTER([Towar G].[Nazwa Towaru].[Nazwa Towaru].members, ([Measures].[Wartosc], [Data Faktury].[Rok].[2004]) > ([Measures].[Wartosc], [Data Faktury].[Rok].[2003])), [Data Faktury].[Rok].[2004 - 2003] >50),[Data Faktury].[Rok].[2004 - 2003], DESC)} ON ROWSFROM BiznesGWHERE ([Measures].[Wartosc], [Klienci G].[Klienci G].[(All)], [Osoby G].[Osoby G].[(All)])
Definiowanie miar i zestawów ad hoc oraz ich wzajemne wykorzystanie
WITHSET [10 najlepszych] AS TOPCOUNT([Klienci G].[Klient].[Klient].members,10, [Data Faktury].[Rok].[2001 + 2003])MEMBER [Klienci G].[Klient].[Suma 10] AS SUM([10 najlepszych], [Measures].[Wartosc])MEMBER [Data Faktury].[Rok].[2001 + 2003] AS ([Measures].[Wartosc], [Data Faktury].[Rok].[2001]) + ([Measures].[Wartosc], [Data Faktury].[Rok].[2002]) + ([Measures].[Wartosc], [Data Faktury].[Rok].[2003])MEMBER [Klienci G].[Klient].[Udzial %] AS ([Klienci G].[Klient].[Suma 10], [Measures].[Wartosc])*100/([Klienci G].[Klient].[All],
[Measures].[Wartosc])SELECT{[Data Faktury].[Rok].[2001 + 2003]} ON COLUMNS,{[10 najlepszych],[Klienci G].[Klient].[Suma 10], [Klienci G].[Klient].[Udzial %]}ON ROWSFROM BiznesG
Definiowanie miar i zestawów ad hoc oraz ich wzajemne wykorzystanie (minimalna notacja)
WITHSET [10 najlepszych] AS
TOPCOUNT([Klient].[Klient].members,10, [Rok].[2001 + 2003])MEMBER [Klient].[Suma 10] AS
SUM([10 najlepszych], [Wartosc])MEMBER [Rok].[2001 + 2003] AS ([Wartosc], [Rok].[2001]) + ([Wartosc], [Rok].[2002]) + ([Wartosc], [Rok].[2003])
MEMBER [Klient].[Udzial %] AS ([Klient].[Suma 10], [Wartosc])*100/([Klient].[All], [Wartosc])
SELECT{[Data Faktury].[Rok].[2001 + 2003]} ON COLUMNS,{[10 najlepszych],[Klient].[Suma 10], [Klient].[Udzial %]}ON ROWSFROM BiznesG