QlikView’s associativa logik

Det kan lätt uppstå missförstånd över vad QlikView’s associativa logik innebär efterssom den INTE är desamma som den associativa datamodellen som är en datamodell presis som  relationsmodellen eller stjärnmodellen inom databasteknologin.  I länken nedan bekräftar QlikView själva att det inte är samma sak och reder dessutom ut vad man menar med det.

http://community.qlikview.com/blogs/theqlikviewblog/2010/08/16/qlikview-is-associative-to-its-very-core

Detta är ett exempel på ett QlikView dokument som tillämpar den associativa tekniken. Gönmarkerad värde är det valda värdet, vitmarkerad värde är det som associeras till det valda och dem gråmarkerade värdena är det som inte associeras med det valda värdet.


Generera datumdimension i SQL server

Hur man genererar en datumdimension i SQL server med ett rekursivt CTE uttryck

Datumdimensionen

Kanske är datumdimensionen den vanligast förekommande dimensionen i en stjärnmodell.  Till skillnad från de flesta övriga dimensioner härstammar inte dimensionsmedlemmarna från ett källsystem. Medlemmarna är givna utifrån den gregorianska tideräkning som används i vår del av världen. Följaktligen är dimensionens utseende snarlikt mellan olika stjärnmodeller. Många BI-utvecklare anser därför att det smidigaste sättet att skapa datumdimensionstabellen är att kopiera den från en annan, redan existerande, stjärnmodell. Nedan tittar vi på ett alternativ till kopierametoden, en metod där datumdimensionen genereras i T-SQL kod.

CTE

Införandet av CTE´s i 2005 versionen av SQL server innebar att vi slapp ofoget med subselects och att vi fick bättre strukturerad och mer lättläst kod. Med CTE´s kom också möjligheten att skriva rekursiva uttryck.  Med rekursiva CTE uttryck är det möjligt att generera rader utan att referera till en tabell.

Följande enkla kodsnutt använder ett rekursivt CTE uttryck för att skapa en datumdimensionstabell.

DECLARE @tDateDay AS DATE = > ’1990-01-01′;

WITH dimDate_CTE AS (
SELECT dateDay = @tDateDay

UNION ALL

SELECT  dateDay = DATEADD(d,1,dateDay)
FROM
dimDate_CTE
WHERE
dateDay<= ’2019-12-31′)

SELECT
dimDateKey = ROW_NUMBER() OVER(ORDER BY dateDay),
dateID =CONVERT(INT,CONVERT(NVARCHAR(8),dateDay,112)),
dateDay = dateDay,
dateDayOfWeek = CONVERT(SMALLDATETIME,DATEPART(DW,dateDay)),
dateWeekNo = CONVERT(SMALLINT,DATEPART(WK,dateDay)),
dateMonthNo = CONVERT(SMALLINT,DATEPART(M,dateDay)),
dateQuarter = CONVERT(SMALLINT,DATEPART(Q,dateDay)),
dateYear = CONVERT(INT,DATEPART(YY,dateday))
INTO dimDate
FROM dimDate_CTE
OPTION (MAXRECURSION 11000)

Vi vill börja generera medlemmar från 1990-01-01. Första raden kod tilldelar detta värde till en lokal variabel. Notera att första raden kod endast fungerar i 2008 versionen eller senare av SQL server. I tidigare versioner existerar inte DATE datatypen. Det går inte heller, i tidigare versioner, att tilldela en lokal variabel ett värde på samma rad som den deklareras.

CTE uttrycket görs rekursivt genom att den andra SELECT frågan i en UNION ALL refererar till den första. Med andra ord, CTE uttrycket anropar sig själv. För varje anrop adderar vi en dag till startdatumet.

WHERE satsen i den andra SELECT frågan är vårt terminerings villkor. Vi vill fortsätta att addera en dag till startdatumet till det når 2019-12-31.

I den nedre SELECT frågan, som refererar till CTE uttrycket, skapar vi de dimensions attribut som vi finner relevanta. Alla attributen baseras på datum. Genererade rader lagras i tabellen dimDate.

Ett rekursivt CTE uttryck får som default endast anropa sig själv 100 gånger, detta för att man inte av misstag skriver uttryck som anropar sig själv i oändlighet. Sista raden kod är en query hint som tillåter rekursiva CTE uttryck, tillhörande denna SELECT sats, att anropa sig själva som mest 11000 gånger. Eftersom vi vet att det är 10958 dagar mellan vårt startdatum och vårt slutdatum känns 11000 som en bra siffra.


Microsoft BI Conference i Stockholm

Härom dagen var det stor BI-konferens i Stockholm med Microsoft som värd. Det talades en del om Self-service BI och om B.I.G data, mycket heta ämnesområden inom BI-världen för tillfället. Microsoft har en produktsvit inom BI som ämnar täcka alla behov som både ledning och användare kan tänkas ha på information och det händer spännande saker framöver. Mer kött på benen kommer i ett senare inlägg, men under tiden kan man läsa om konferensen och dess innehåll här.


Qlikview set analysis vs MDX

I come from a Microsoft background but have made a couple of forays into the world of Qlikview. I noticed that just like MDX is used to enhance reports and cubes when working in the Microsoft BI environment, Qlikview provides set analysis expressions as a tool for sorting and querying subsets of data within a Qlikview document. The set analysis syntax is quite different from MDX so I thought a little comparison using the AdventureWorks data structure might be worthwhile.

In MDX a query scoped member or calculated measure totaling the sales amount for male customers would look like this:

sum([DimCustomer].[Gender].&[M],[Measures].[Sales Amount])

Translated into a Qlikview set analysis expression we end up with the following:

=sum({$<Customer.Gender = {'M'}>} OrderDetails.[Sales Amount])

An MDX scoped member or calculated measure totaling the sales for all male customers in Germany and France would be defined using a crossjoin (note the * operator):

sum({[DimSalesTerritory].[SalesTerritoryCountry].&[France],
[DimSalesTerritory].[SalesTerritoryCountry].&[Germany]} *
[DimCustomer].[Gender].&[M], [Measures].[Sales Amount])

Using Qlikview set analysis the above would look like this:

=sum({$ < Customer.Gender = {'M'},
SalesTerritory.SalesTerritoryCountry =
{'Germany','France'}>} OrderDetails.SalesAmount)

A total excluding France and Germany would look like this in MDX:

sum(except([DimSalesTerritory].[SalesTerritoryCountry].children,
{[DimSalesTerritory].[SalesTerritoryCountry].&[France],
[DimSalesTerritory].[SalesTerritoryCountry].&[Germany]},
[Measures].[Sales Amount])

using Qlikview set analysis we get this:

=sum({$ <SalesTerritory.SalesTerritoryCountry =
-{'Germany','France'} >} } OrderDetails.SalesAmount)

An mdx query calculating the two years with the highest sales from the AdventureWorks cube would look like this:

SELECT
sum(TOPCOUNT([DimDate].[CalendarYear].[CalendarYear], 2,
[Measures].[Sales Amount]),[Measures].[Sales Amount])
ON 0
from [AWModel]

In Qlikview you would create a chart displaying Sales Amount by Calendar Year and then select Properties–>Dimension Limits and check the ”Select which values are displayed” check box so you can set the chart to display only the two largest values.

Or you can create a list box for Calendar Year next to your chart and type the following set analysis expression into the search box:

=rank(sum(OrderDetails.SalesAmount))<=2

and press enter. The two years with the largest sales are now selected by the expression you just created.

I think it is quite safe to assume that one of the reasons it is quite time consuming to replace an OLAP-cube with a Qlikview document or vice versa, are the syntactical differences.

Notes: I have used the sum function on the MDX-statements for the sake of clarity. It is actually not needed since the property of the measure itself is set to sum in the SSAS cube definition. If we substitute the ”$” for ’1′, our selections will be independent of any selections in the Qlikview document.


En jämförelse mellan Qlikview set analys och MDX-frågor

Undertecknad härstammar från Microsoftbakgrund men har gjort några kortare inkursioner in i Qlikviews värld. En sak jag upptäckt är att precis som MDX används för ställa frågor och sortera data i kuber, så används set analys uttryck i Qlikview i liknande syfte. Syntaxen skiljer sig dock en del varför jag tycker att en jämförelse är på sin plats.

I MDX så ser en frågesammanhangsberoende medlem eller ett kalkylerat mått som räknar ut totalen för alla manliga kunder ut på följande vis:

sum([DimCustomer].[Gender].&[M],[Measures].[Sales Amount])

Översatt till ett set analys-uttryck så får vi följande:

=sum({$<Customer.Gender = {'M'}>} OrderDetails.[Sales Amount])

I MDX så skulle en frågesammanhangsberoende medlem eller ett kalkylerat mått som räknar ut totalen för alla manliga kunder i Tyskland och Frankrike använda sig av en crossjoin och se ut på följande vis:

sum({[DimSalesTerritory].[SalesTerritoryCountry].&[France],
[DimSalesTerritory].[SalesTerritoryCountry].&[Germany]}
* [DimCustomer].[Gender].&[M],
[Measures].[Sales Amount])

Ovanstående uttryck omvandlat till ett Qlikview set analys-uttryck ser ut så här:

=sum({$ < Customer.Gender = {'M'},
SalesTerritory.SalesTerritoryCountry
= {'Germany','France'}>} OrderDetails.SalesAmount)

En total som utesluter Tyskland och Frankrike ser ut så här om man använder sig av MDX:

sum(except([DimSalesTerritory].[SalesTerritoryCountry].children,

{[DimSalesTerritory].[SalesTerritoryCountry].&[France],
[DimSalesTerritory].[SalesTerritoryCountry].&[Germany]}, [Measures].[Sales Amount])

Ovanstående uttryck omvandlat till ett Qlikview set analys-uttryck ser ut så här:

=sum({$ <SalesTerritory.SalesTerritoryCountry = 
-{'Germany','France'} >} }
OrderDetails.SalesAmount)

En MDX-fråga som räknar ut de två åren med störst försäljning från AdventureWorks-kuben skulle se ut så här:

SELECT
sum(TOPCOUNT([DimDate].[CalendarYear].[CalendarYear], 2,
[Measures].[Sales Amount]),[Measures].[Sales Amount])
ON 0
from [AWModel]

I Qlikview skulle man lösa ovanstående med att skapa ett diagram som visar Sales Amount över Calender Year–>Dimension Limits och välj ”Select which values are displayed” check box så du kan ställa diagrammet till att visa endast de två största värdena.

En annan möjlig lösning är att skapa en list box och skriva följande set analys-uttryck i sökrutan:

=rank(sum(OrderDetails.SalesAmount))<=2

och trycka enter.

P.g.a. skillnaderna i syntax så är det ett rimligt antagande att det krävs en del jobb att ersätta en SSAS-kub med ett Qlikview-dokument eller vice versa.

Noteringar: Jag har använt sum-funktionen på MDX-uttrycken för att öka tydligheten. Uttrycket behövs egentligen inte då måttet är satt till att vara en sum i själva kubdefinitionen. Det är också värt att notera att vi kan byta ’$’ mot ’1’ i set analys-uttrycken om vi vill göra dem oberoende av gjorda val i Qlikview-dokumentet.


DEEP DIVE Microsoft SQL Server 2012 & SQL Azure

Den andra april bjuder SQLUG in till en heldag på Microsoft i Akalla där de går igenom SQL Server 2012 och Azure.

Detta får ni inte missa, speciellt med tanke på vem som är inbjuden talare!

Tidsschema:

08:30-09:00         Registrering, Kaffe
09.00-10.00         SQL Server 2012 Overview
10.00-10:45         T-SQL Deep-dive – What is new in SQL Server     2012 & SQL Azure
10:45-11:00         Paus
11:00-11:45         Making sense of your Unstructured data in SQL Server 2012
11:45-12:45         Lunch
12:45-13:45         Enterprise Information Management in SQL Server 2012, Keeping you data clean!
13:45-14:30         Developing Applications for SQL Azure
14:30-14:50         Paus
14:50-15:30         Performance tuning SQL Server 2012
15:30-16:00         Ask the experts

https://msevents.microsoft.com/CUI/EventDetail.aspx?EventID=1032507143&culture=sv-SE


Microsoft Business Intelligence Conference 2012

Image

Vill påminna alla ni BI-fantaster att Microsoft har sin årliga Business Intelligence konferens i Stockholm den 27 Mars och den 28 Mars i Göteborg.

In och boka!

http://www.microsoft.com/sv-se/business/losningsomraden/business-intelligence-conference.aspx

Vi från Kentor kommer vara där hela dagen som åhörare, så är ni där är det bara att komma fram och säga hej.


Vad är BI del 3

Del 3

I de två tidigare delarna har vi definierat BI som uppföljningen av en verksamhets affärsprocess. Samt identifierat de funktionella komponenter som krävs vid data-förberedelse i en enterprise BI miljö.

Vi kommer i detta inlägg identifiera resterande komponenter i vår enterprise BI-stack. Avslutningsvis använder vi den kompletta BI-stack modellen för att identifiera tre vanligt förekommande varianter av vår definition och vilka implikationer de tre varianterna har på en verksamhets BI-mognad. Läs mer


Ett resonemang

Ett intressant resonemang, men är det verkligen så enkelt?

http://xkcd.com/936/


Vad är Business Intelligence

Del 2

I del 1 påbörjade vi vårt mycket ambitiösa projekt med att definiera BI. Vi bestämde oss för att se BI som uppföljningen av en verksamhets affärsprocesser.

I detta andra inlägg ska vi påbörja arbetet med att skapa en modell som definiera de funktionella komponenter som bygger en värdeskapande enterprise BI miljö. En enterprise BI miljö syftar på en miljö som stöder en gemensam uppföljning av en verksamhets samtliga affärsprocesser, a single point of truth. BI´s heliga Graal. Modellen kommer att vara en komponent stack, där varje komponent placeras in efter sitt beroende förhållande till övriga komponenter.

Källsystem

Exekveringsprocessen matar uppföljningsprocessen med data. Utan exekvering ingen uppföljning. Därför placerar vi exekvering som grunden i vår komponent stack. Vi fortsätter vår trend av förenkling och definierar exekveringsprocessens funktionella komponenter som källsystem.

Data förberedelse

Affärsdata finns utspritt över en mängd olika källsystem runt om i verksamheten. Ofta finns det flera olika system som stöder samma del-affärsprocess.  För att skapa en samlad bild av verksamheten måste affärs data samlas in och göras enhetlig. Denna process kallar vi för data förberedelse (data preparation, ibland även kallat data management). Ansvaret för dataförberedelse delas mellan exekveringsprocessen och uppföljningsprocessen. Desto tidigare i exekveringsprocessen ett affärsobjekt anpassas till gemensamma definitioner desto enklare blir det att följa upp.

Vi delar in data förberedelse i fyra komponenter.

Data integration

Ansvarar för integrationen mellan exekvering och uppföljning. Oftast behöver en IT process två integrationskomponenter. En för integration mellan olika exekverings komponenter. Denna är meddelande orienterad och hanterar en transaktion eller ett affärsobjekt åt gången. Den andra integrationskomponenten stöder integrationen mellan exekvering och uppföljning. Denna är batch orienterad och hanterar stora mängder transaktioner eller affärsobjekt åt gången. Vår komponent syftar på den batch orienterade.

Data kvalité

Dålig data kvalité i källsystemen är oftast den största utmaningen i ett BI projekt. Dålig kvalité leder till att stora mängder affärsdata blir oanvändbar och att värdet av verksamhetens data historik minskar. Denna komponent ansvarar för att all affärsdata lever upp till de kvalitéts krav som ställs för en meningsfull uppföljning.

Master data management (MDM)

Samma affärsobjekt används ofta i en mängd olika källsystem. Oftast har dessa system lite olika definitioner på affärsobjekten. Ett klassiskt exempel är kund. Det är sällan som det finns en rådande definition av vad en kund är i alla källsystem. MDM komponenten har som uppgift att implementera en rådande definition av varje affärsobjekt och se till att all källdata anpassas till denna definition. I uppföljningssammanhang accepteras denna definition som den enda sanningen.

Datawarehouse

Modellerar data till att passa för de specifika krav som ställs på uppföljning. Modeller som är anpassade för analysera stora mängder data. I icke enterprise miljöer är ofta de underliggande komponenterna (Data integration, Data kvalité, Master Data Management) naturligt integrerade delar av ett datawarehouse. I icke enterprise miljöer existerar ofta flera datawarehouse som var för sig täcker olika delar av verksamhetens affärsdata.

BI stacken

Om vi placerar in ovan definierade komponenter i en och samma modell ser den ut som nedan. Vi kallar modellen för BI stacken.

I nästa inlägg…

Definierar vi de översta nivåerna i BI stacken, komponenter för data användning. Samt tittar på några andra, mindre omfattande men vanligt förekommande, definitioner av BI och vilka implikationer dessa varianter har på en verksamhets IT mognad.


Följ

Få meddelanden om nya inlägg via e-post.