18. srpna 2015

MDX tutorial 6. – Setové operace

V minulém díle tutorialu jsme se zaměřili na vybrané setové funkce. Čas od času člověk potřebuje provést i nějakou operaci mezi množinami. Nejprve trocha teorie a potom i pár praktických příkladů a modelových situací kde s množinovými operacemi přijdu nejčastěji do styku.
Připomínám, že pokud tutorial náhodou nečtete od začátku aktuální verze projektu je k dispozici zde
http://tinyurl.com/pxfnrkw, postaveno nad demo databází AdventureWorksDW2012 z Codeplexu http://tinyurl.com/qd3bbg Projekt může být v průběhu času dále uzpůsobován potřebám tutorialu.
Na obrázku máme množiny A a B

Jaké máme množinové operace?
Operace
Popis
Funkce
Operátor
Sjednocení
Když dáme dohromady množinu A i B
Union
+
Rozdíl
Z množiny A vyloučíme množinu B
Except
-
Průnik
Co mají množiny společného
Intersect
Kartézský součin
Každý prvek množiny A s každým prvkem množiny B
Crossjoin
*

Sjednocení / Union({Set1},{Set2},[All])
Věřím, že SQL znalí čtenáři už operaci UNION někdy použili v SQL. Kdo se s touto úlohou zatím nesetkal, pak úkolem sjednocení je vrátit položky které jsou v obou množinách bez duplicit (Union) případně s duplicitami (Union All)
V minulém článku http://www.neoral.cz/2015/08/mdx-tutorial-5-setove-funkce.html jsme si ukázali funkci Topcount. Chtěl bych provést sjednocení množiny Deseti nej modelů produktů dle prodejnosti přes Internet a množiny top deseti přes obchodníky (Reseller).
Dva samostatné dotazy, které vrátí top 10 přes daný kanál prodeje máme zde
SELECT
       {}
ON COLUMNS,
       Topcount(
       [Dim Product].[Model].[Model]
       ,10
       ,[Measures].[Reseller Sales]
       )
ON ROWS
FROM [MDX Tutorial]

SELECT
       {}
ON COLUMNS,
       Topcount(
       [Dim Product].[Model].[Model]
       ,10
       ,[Measures].[Internet Sales]
       )
ON ROWS
FROM [MDX Tutorial]
Sjednocení se dá provést buď operátorem +, nebo funkcí Union. Plusko je jednodušší, tak používám primárně to. Po funkci sahám pouze pokud potřebuji „Union All“ Dotaz pluskovou syntaxí by vypadal následovně
SELECT
       {}
ON COLUMNS,
       Topcount(
       [Dim Product].[Model].[Model]
       ,10
       ,[Measures].[Reseller Sales]
       )
       +
       Topcount(
       [Dim Product].[Model].[Model]
       ,10
       ,[Measures].[Internet Sales]
       )
ON ROWS
FROM [MDX Tutorial]
Získáme

Rozdíl množin/ Except({Set1},{Set2},[All])
Co je v první množině a není ve druhé množině? Rozdíl se dá nejjednodušeji napsat znaménkem –
Takže na otázku co se prodávalo dobře přes Reseller a ne přes Internet si odpovíme
SELECT
       {}
ON COLUMNS,
       Topcount(
       [Dim Product].[Model].[Model]
       ,10
       ,[Measures].[Reseller Sales]
       )
       -
       Topcount(
       [Dim Product].[Model].[Model]
       ,10
       ,[Measures].[Internet Sales]
       )
ON ROWS
FROM [MDX Tutorial]

Průnik množin / Intersect({Set1},{Set2},[All])
Co se prodávalo dobře jak přes Internet tak přes Reseller se nedá napsat znaménkem, musíme jej vypsat jako funkci
SELECT
       {}
ON COLUMNS,
intersect(  
       Topcount(
       [Dim Product].[Model].[Model]
       ,10
       ,[Measures].[Reseller Sales]
       )
       ,
       Topcount(
       [Dim Product].[Model].[Model]
       ,10
       ,[Measures].[Internet Sales]
       )
       )
ON ROWS
FROM [MDX Tutorial]

Kartézskému součinu jsme se věnovali v 2. díle tutorialu http://www.neoral.cz/2015/05/mdx-tutorial-2-prace-se-setem.html
Tolik k syntaxi základních operací, pojďme se podívata na
Aplikace, tipy, triky
Velmi častým požadavkem je, vyloučit vybrané skupiny/položky z reportu. Například chtěl bych vypsat prodeje všech modelů všech kategorií kromě Accessories „Bikes“ a to tentokrát například na řádcích
SELECT
       {[Measures].[Reseller Sales]}
ON COLUMNS,
non empty
       {
       /*Všechny kategorie*/
       [Dim Product].[Category].[Category]-
       /*Vyloučená množina*/
       [Dim Product].[Category].&[Bikes]
       }
       *[Dim Product].[Model].[Model]
ON ROWS
FROM [MDX Tutorial]
Nebo mě zajímají prodeje všeho, kromě kategorie Bikes, tudíž vyloučit množinu v klauzuli where
SELECT
       {[Measures].[Reseller Sales]}
ON COLUMNS
FROM [MDX Tutorial]
WHERE -{[Dim Product].[Category].&[Bikes]}

Případně mě zajímají všechny úrovně produktové hierarchie kromě nejnižšího levelu Product
SELECT
       {[Measures].[Reseller Sales]}
ON COLUMNS,
NON EMPTY
       [Dim Product].[Category-Subcategory-Model-Product].members -
       [Dim Product].[Category-Subcategory-Model-Product].[Product]
ON ROWS
FROM [MDX Tutorial]
Chceme řadit data abecedně, jen chceme kategorii „Další“, aby se zobrazovala na konci nikoliv v prostředku dle abecedního řazení. Můžeme simulovat na kategorii Bikes kterou napřed – vyhodíme a poté ji plusem přidáme zpátky na konec :)
SELECT
       {[Measures].[Reseller Sales]}
ON COLUMNS,
NON EMPTY
       [Dim Product].[Category].[Category]-
       [Dim Product].[Category].&[Bikes]+
       [Dim Product].[Category].&[Bikes]
ON ROWS
FROM [MDX Tutorial]
Závěr

Bez setových operací v závěru kapitoly se v praxi nedá dost dobře fungovat. Tudíž je vhodné se je naučit. Časem se ale budete plusy a mínusy bouchat do MDX skriptů tak automaticky, že Vám to ani nepřijde

Žádné komentáře:

Okomentovat