#sqlsat257#sqlsatveronaNovember 9th, 2013
SQL Saturday #257 – Verona, Italy
SQL Saturday #257
Verona, Italy
Introduction DAX
09/11/2013 |
#sqlsat257#sqlsatveronaNovember 9th, 2013
Sponsor & Media Partners
#sqlsat257#sqlsatveronaNovember 9th, 2013
Organizers
#sqlsat257#sqlsatveronaNovember 9th, 2013
Marco Pozzan
Lavoro con SQL server dalla versione 2000 Lavoro nella BI dal 2005 Presidente della community 1nn0va (
www.innovazionefvg.net) Project manager del reparto Business Intelligence
della Servizi CGN (www.cgn.it) Consulente SQL Server , DW Riferimenti:
twitter: @marcopozzan email: [email protected] site: www.marcopozzan.it
#sqlsat257#sqlsatveronaNovember 9th, 2013
Agenda
Che cosa è Power Pivot? Demo su Power Pivot Che cosa è DAX? Colonne calcolate e campi calcolati Evaluation Context Calculate Demo in DAX
#sqlsat257#sqlsatveronaNovember 9th, 2013
Che cosa è Powerpivot?
Free AddIn per Microsoft Excel 2010 e 2013 Diverse versioni per 32/64 bit Non servono SQL Server o altri prerequisiti Motore di analisi molto potente basato su
SSAS di SQL Server 2012
#sqlsat257#sqlsatveronaNovember 9th, 2013
Versioni
Viene installato: Client-side: dentro ad Excel Server-side: Integrato su SharePoint o SQL
Server 2012(nuova istanza SSAS)
nella versione client-side l’engine SSAS gira in-process con Excel
#sqlsat257#sqlsatveronaNovember 9th, 2013
Nuovo engine SSAS 2012
Utilizza il motore Vertipaq che è un database colonnare ad alta compressione
Lavora completamente in memoria Niente I/O, aggregazioni o altro… IMBI = Nuovo modo di pensare agli algoritmi
#sqlsat257#sqlsatveronaNovember 9th, 2013
Powerpivot in velocità
Importare i dati Relazioni tra tabelle Slicer
#sqlsat257#sqlsatveronaNovember 9th, 2013
Vantaggi PowerPivot
Rapidità No ETL (Power Query) Modello metadati Integrazione sorgenti eterogenee
Condivisione Soprattutto con Sharepoint
Espressività Relazioni e Dax
#sqlsat257#sqlsatveronaNovember 9th, 2013
Svantaggi PowerPivot
Non ci sono Etl per pulire i dati Qualità del dato? Volume di dati
Attenzione che questi non sono problemi!!! Come potrebbero sembrare
#sqlsat257#sqlsatveronaNovember 9th, 2013
Che cosa è DAX?
Progettato per lavorare all’interno di una PivotTable
Linguaggio di programmazione del nuovo SSAS si usa su PowerPivot e Tabular
Simile ad Excel (Dicono ) Nessun concetto di «riga» e «colonna» Diverso sistema di tipi
Mix tra MDX, SQL, EXCEL
#sqlsat257#sqlsatveronaNovember 9th, 2013
Tipi di dato in DAX
Non numerici: String Binary Objects (Power View)
Tipi numerici: Currency Integer Real DateTime
(intero: gg 30/12/1899, decimale: frazione del giorno)
TRUE / FALSE (Boolean)
#sqlsat257#sqlsatveronaNovember 9th, 2013
Gestione dei Tipi
Gli operatori non sono strongly typed ("1"+1) Il risultato dipende dall’operatore Operator Overloading (pericoloso ) Esempio di conversioni 1 & 2 = "12" "1" + "2" = 3
#sqlsat257#sqlsatveronaNovember 9th, 2013
Colonne in DAX 1/2
'TableName’[ColumnName]
Gli apici possono essere omessi solo se la TableName non contiene spazi (Non lo fate )
=FactInternetSales[OrderDate]
#sqlsat257#sqlsatveronaNovember 9th, 2013
Colonne in DAX 2/2
TableName può essere omesso e quindi cercherà nella tabella corrente Meglio non farlo in quanto si fatica a capire le
formule
Le parentesi quadre sono obbligatorie
=[OrderDate]
#sqlsat257#sqlsatveronaNovember 9th, 2013
Colonne calcolate
Sono definite in Dax e sono persistite su DB Usano altre colonne Lavorano sempre nella «riga corrente» Quando scrivo FactInternetSales[OrderDate]
Valore della colonna OrderDate Nella tabella FactInternetSales Per la riga corrente Diverso per ogni riga
#sqlsat257#sqlsatveronaNovember 9th, 2013
Misure (Calculated Fields)
Si scrivono con DAX Non sono memorizzate sul DB Non lavorano riga per riga Usano tabelle ed aggregatori Non hanno il concetto di «riga corrente»
Non posso scrivere la seguente formula
=FactInternetSales[OrderDate]
#sqlsat257#sqlsatveronaNovember 9th, 2013
Definire i nomi giusti
Attenzione che se cambiate il nome delle colonne bisogna cambiarlo manualmente nella misure!!! Quindi definite subito i nomi giusti
#sqlsat257#sqlsatveronaNovember 9th, 2013
Colonne calcolate e Misure
Supponiamo di voler calcolare il margine con una colonna calcolata:
Posso aggregare la colonna margine con una misura
=FactInternetSales[SalesAmount]-FactInternetSales[TotalProductCost]
Margine:=SUM(FactInternetSales[Margine])
#sqlsat257#sqlsatveronaNovember 9th, 2013
Colonne calcolate e Misure
% del margine rispetto al fatturato (margine%)
Questa espressione non va bene se la devo calcolare riga per riga perchè
Devo usare una misura
=FactInternetSales[Margine] / FactInternetSales[SalesAmount]
Margine%:=SUM(FactInternetSales[Margine]) / SUM(FactInternetSales[SalesAmount])
#sqlsat257#sqlsatveronaNovember 9th, 2013
Considerazioni sulle Misure
Quando definiamo un misura bisogna: Definire il nome della tabella a cui appartiene
Le misure sono globali al modello Non ci possono essere due misure con lo stesso
nome in tabelle diverse Si possono spostare da una tabella all’altra questo
non si può fare con le colonne calcolate Non fare mai riferimento ad una misura con la
tabella si confonde con le colonne calcolate
#sqlsat257#sqlsatveronaNovember 9th, 2013
Conclusioni 1/2
Le colonne usano spazio e le misure CPU Vengono calcolate in momenti diversi Hanno scopi diversi Hanno strutture diverse Vengono gestite in modi diversi
#sqlsat257#sqlsatveronaNovember 9th, 2013
Conclusioni 2/2
Misure quando (90%) Si calcolano rapporti Si calcolano percentuali Si calcolano aggregazioni complesse
Colonne calcolate quando (10%) Si necessita di slicer o filtri sui valori L’espressione è calcolata sulla riga corrente
#sqlsat257#sqlsatveronaNovember 9th, 2013
Funzioni conteggio
COUNTROWS: conta le righe in tabella COUNTBLANK: conta i bianchi COUNTA: conta tutto anche gli spazi COUNT : conta solo le colonne numeriche
Per compatibilità con Excel
DISTINCTCOUNT: conta le righe distinte Multidimensional -> measure group con una
misura distinctcount .. lenta come una lumaca
#sqlsat257#sqlsatveronaNovember 9th, 2013
Errori DAX 1/2
È Possibile intercettare gli errori [SalesAmount]/[Margin] potrebbe fallire
Errori di conversione Operazioni aritmetiche Valori vuoti o mancanti
ISERROR è una funzione che torna TRUE o FALSE se c’è stato un errore o meno durante la validazione
#sqlsat257#sqlsatveronaNovember 9th, 2013
Errori DAX 2/2
IFERROR (Espressione, alternativa) è una funzione che torna l’alternativa se c’è un errore altrimenti l’espressione
Sia IFERROR e ISERROR sono molto lente quindi fate attenzione a come le usate nelle colonne calcolate
#sqlsat257#sqlsatveronaNovember 9th, 2013
Funzioni di Aggregazione
Lavorano solo su colonne numeriche Sono le seguenti:
SUM AVERAGE MIN MAX
Aggrego solo colonne e NON espressioni SUM(Order[Quantity]) SUM(Order[Quantity]) * Orders[Quantity])
#sqlsat257#sqlsatveronaNovember 9th, 2013
Funzioni X di Aggregazione
Per aggregare espressioni devo usare le funzioni X. Iterano sulla tabella e valutano l’espressione per ogni riga
Ricevono due parametri la tabella su cui iterare e la formula da valutare
Sono: SUMX,AVERAGEX,MINX,MAXXSUMX (
Sales,Sales[Price] * Sales[Quantity]
)
#sqlsat257#sqlsatveronaNovember 9th, 2013
Dettaglio della funzione X
Prima calcola i parametri interni e poi fa la somma
Le colonne devono essere tutte sulla stessa tabella oppure uso RELATED (se c’è una relazione)
Sono molto lente ma non uso Spazio
#sqlsat257#sqlsatveronaNovember 9th, 2013
Alternativa alle funzioni X
In alternativa alle funzioni X devo creare una colonna calcolata e poi aggregare su quella colonna Sono molto veloce ma uso spazio
#sqlsat257#sqlsatveronaNovember 9th, 2013
Funzioni logiche
AND (poco usato) oppure si usa && OR (poco usato) oppure si usa || IF IFERROR NOT (poco usato) SWITCH
#sqlsat257#sqlsatveronaNovember 9th, 2013
Switch
Color :=IF(DimProduct[Color] = "Red", "Rosso",
IF(DimProduct[Color] = "Yellow", "Giallo", "Altro"))
Color :=Switch (
DimProduct[Color],"Red", "Rosso","Yellow", "Giallo","Altro"
)
#sqlsat257#sqlsatveronaNovember 9th, 2013
Funzioni informative
Completamente inutili (perché non prendono le espressioni ma solo colonne) ISNUMBER ISTEXT ISNONTEXT
Utili ISBLANK ISERROR
Ma se non lo sappiamo noi (che abbiamo creato la colonna) se è un numero o un testo chi lo deve sapere (by Alberto Ferrari)
#sqlsat257#sqlsatveronaNovember 9th, 2013
Funzione DIVIDE
Con divide si evita di fare il controllo con IF se il denominatore è 0 IF( Sales[Price] <> 0, Sales[Quantity] /
Sales[Price],0)
DIVIDE(Sales[Quantity], Sales[Price],0)
#sqlsat257#sqlsatveronaNovember 9th, 2013
Funzioni sulle Date
Funzioni classiche per le date:
DATE ,DATEVALUE, DAY, EDATE,EMONTH ,HOUR, MINUTE, MONTH, NOW, SECOND, TIME, TIMEVALUE, TODAY (interessante!!!), WEEKDAY, WEEKNUM, YEAR, YEARFRANC
Funzioni Time intelligence
#sqlsat257#sqlsatveronaNovember 9th, 2013
Evaluation context 1/3
Caratterizza DAX da qualsiasi altro linguaggio
Sono simili alle clausole where delle query MDX in SSAS
Contesto in cui viene valutata una formula Filter Context , RowContext
#sqlsat257#sqlsatveronaNovember 9th, 2013
Evaluation context 2/3
Filter Context: Set di righe attive per il calcolo che poi vengono
aggregate. Il filtro che viene dalla PivotTable è il filter
context. Definito da filtri, righe ,colonne e slicers.
#sqlsat257#sqlsatveronaNovember 9th, 2013
Evaluation context 3/3
Row Context: Contiene una sola riga Riga corrente durante i loop Introdotto dalle formule X non dalla tabella Pivot Questo concetto è nuovo rispetto MDX perché
non siamo abituati a lavorare foglia per foglia ma solo sul contesto.
#sqlsat257#sqlsatveronaNovember 9th, 2013
I due contesti esistono sempre…
Filter context: Filtra le tabelle Può essere vuoto: si vede solo il totale Viene utilizzato dalle funzioni di aggregazione In una colonna calcolata è pari a tutto il database
perché non c’è pivot table
Row context: Naviga le righe attive nel filter context Può essere vuoto: non ci sono iterazioni
#sqlsat257#sqlsatveronaNovember 9th, 2013
Con più tabelle?
#sqlsat257#sqlsatveronaNovember 9th, 2013
I due contesti esistono sempre…
Filter context: Il filtro si propaga dal lato uno al lato molti delle
relazioni Le relazioni hanno un verso ed è molto importante
a differenza di SQL (inner,left,...) si applica una volta sola (+ performance)
Row context: Se ne frega delle relazioni - performance (row context ha velocità) Posso usare il comando RELATED
#sqlsat257#sqlsatveronaNovember 9th, 2013
Esempio di Filter Context
#sqlsat257#sqlsatveronaNovember 9th, 2013
Funzioni su tabelle (Table Functions)
Funzioni che ritornano tabelle: FILTER
(aggiunge filtro ed è un iteratore!!!)
ALL (rimuove filtri e restituisce o una colonna o una tabella)
VALUES (valori di una colonna compresi i blank)
DISTINCT (valori distinti di una colonna non mostra i blank)
RELATEDTABLE (tutti i valori collegati alla riga corrente)
Il risultato si usa in altre funzioni e possono essere combinate assieme
#sqlsat257#sqlsatveronaNovember 9th, 2013
Filter
#sqlsat257#sqlsatveronaNovember 9th, 2013
All
#sqlsat257#sqlsatveronaNovember 9th, 2013
Mescolare i filtri
#sqlsat257#sqlsatveronaNovember 9th, 2013
VALUES
Ritorna la tabella con una sola colonna contenente tutti i possibili valori della colonna visibili nel contesto corrente
Quando il risultato è formato da una colonna e una riga può essere usato come scalare
AnniSelezionati:=COUNTROWS(VALUES(Dati[Year]))
#sqlsat257#sqlsatveronaNovember 9th, 2013
RELATEDTABLE
Se mi trovo nella tabella degli store e voglio sapere il numero di vendite per store uso la RELATEDTABLE
=COUNTROWS (RELATEDTABLE(Dati))
#sqlsat257#sqlsatveronaNovember 9th, 2013
Considerazioni
Per ora abbiamo visto che si può: aggiunge filtro rimuove filtri e restituire intera tabella o una
colonna mixare i filtri
…..ma se volessi: ignorare solo una parte del filter context e non
tutto? aggiungere una condizione al filter context o
modificare una condizione esistente?
#sqlsat257#sqlsatveronaNovember 9th, 2013
Calculate
E’ una funzione molto semplice ma complicata CALCULATE(
Expression,Filter1,….FiltroN
)
Valuto prima i filtri (AND) e poi l’espressione I filtri rimpiazzano pezzi del contesto corrente Dentro un filtro di calculate opero solo su una
colonna o sull’intera tabella
#sqlsat257#sqlsatveronaNovember 9th, 2013
Calculate – ordine di valutazione
Ordine di valutazioneCALCULATE (
CALCULATE(EspressioneALL([Sales Territory Country])
); [Sales Territory Country] = "Italy"
) LA CALCULATE valuta il primo parametro dopo
aver valutato il secondo. Tutti i filtri sono elaborati in parallelo e sono indipendenti l’uno dall’altro.
12
3
#sqlsat257#sqlsatveronaNovember 9th, 2013
Calculate – condizioni di filtro
Boolean conditions: lavora su singola colonna e specifica una condizione da rimpiazzare su una colonna esistente
SalesAmountWhite:= CALCULATE( SUM(FactInternetSales[SalesAmount]); DimProduct[Color] = " White" )
#sqlsat257#sqlsatveronaNovember 9th, 2013
Calculate – condizioni di filtro
List of values: esattamente la lista di valori che voglio vedere nel nuovo filtro. E’ sotto forma di tabella e tutte le colonne della tabella saranno parte del filtro
ProductM100 := CALCULATE( SUM(FactInternetSales[SalesAmount]); DimProduct[ListPrice] > 1000 )
#sqlsat257#sqlsatveronaNovember 9th, 2013
Calculate – condizioni errate nel filtro
Quindi questa formula non posso scriverla
ProductLMC := CALCULATE( SUM(FactInternetSales[SalesAmount]); DimProduct[ListPrice] > DimProduct[StandardCost] ))
ProductLMC := CALCULATE( SUM(FactInternetSales[SalesAmount]); FILTER(DimProduct, DimProduct[ListPrice] > DimProduct[StandardCost] ))
Il filtro è una boolean condition che lavora su una sola colonna e in questo caso ci sono troppe colonne nell’espressione di filtro (ListPrice e StandardCost) quindi va in errore
Quindi si usa il FILTER
#sqlsat257#sqlsatveronaNovember 9th, 2013
Calculate
#sqlsat257#sqlsatveronaNovember 9th, 2013
Attenzione alle funzioni X
Queste due formule sono equivalenti:
La versione senza X è più veloce Non richiede iterazioni
Calculate TotX:= CALCULATE( SUMX(Dati;
Dati[Total Cost] ); ALL(Dati[Quarter])
)
Calculate Tot:= CALCULATE( SUM( Dati[Total Cost]);
ALL(Dati[Quarter]) )
#sqlsat257#sqlsatveronaNovember 9th, 2013
Calculate – attenzione al filter context
Attenzione nella valutazione delle formule per quanto riguardo il filter context con CALCULATE
ProductM100:= CALCULATE (
SUM(FactInternetSales[SalesAmount]),FILTER(
DimProduct,
DimProduct[ListPrice] >= 100 ) )
La DimProduct viene valutata nel filter context originale prima che entri in gioco la CALCULATE
#sqlsat257#sqlsatveronaNovember 9th, 2013
Calculate – attenzione al filter context
Attenzione nella valutazione delle formule per quanto riguardo il filter context con CALCULATE
ProductM100_BIS:= CALCULATE (
SUM(FactInternetSales[SalesAmount]),FILTER(
ALL(DimProduct),
DimProduct[ListPrice] >= 100 ) )
La DimProduct subisce la ALL e il nuovo filter context su cui verrà valutata la SUM sono tutte le colonne
#sqlsat257#sqlsatveronaNovember 9th, 2013
Calculate – Context transition
= SUM(FactInternetSales[SalesAmount]);
= CALCULATE(SUM(FactInternetSales[SalesAmount]));
Supponiamo di scrivere le seguenti colone calcolate nella tabella DimProduct. Sono uguali?
#sqlsat257#sqlsatveronaNovember 9th, 2013
Calculate – Automatic Calculate
Ammontare := SUM(FactInternetSales[SalesAmount])
Vendite = SUMX(DimCustomer, Ammontare)
Vogliamo una colonna calcolata che per ogni prodotto e per ogni cliente fornisca l’ammontare delle vendite.
L’eleganza di CALCULATE
Questa viene eseguita in un row context per effetto della SUMX
La misura Ammontare per effetto della Automatic Calculateviene eseguita come fosse CALCULATE(Ammontare)
Quindi si applica il context transition sul row context ottenendo un filter context delle vendite del customer corrente per il prodotto correnteQuella semplice espressione nella colonna calcolata estrae le righe di vendita del prodotto per il cliente specifico per tutti i prodotti.
#sqlsat257#sqlsatveronaNovember 9th, 2013
Analisi di Pareto e l’analisi ABC
L’80 % degli effetti viene dal 20 percento delle cause L’80% delle vendite proviene dal 20% dei clienti
L’analisi di pareto stà alla base della classificazione ABC Si classificano gli oggetti in questione secondo
tre classi A = oggetti che portano >= 70% di guadagno B = oggetti che portano >=20% < 70% di guadagno C = oggetti che portano <20% di guadagno
#sqlsat257#sqlsatveronaNovember 9th, 2013
Analisi di Pareto e l’analisi ABC
Per ogni riga il totale venduto TotalSales
Calcolare tutti i prodotti con il totale venduto maggiore al venduto del prodotto della riga RunningTotalSales
=CALCULATE( SUM(FactInternetSales[SalesAmount]))
= SUMX( FILTER( DimProduct;
DimProduct[TotalSales] >= EARLIER(DimProduct[TotalSales]) ); DimProduct[TotalSales] )
#sqlsat257#sqlsatveronaNovember 9th, 2013
Analisi di Pareto e l’analisi ABC
calcolare la percentuale delle vendite per quel prodotto rispetto al totale delle vendite
Con degli IF visualizziamo le etichette A,B,C
=DimProduct[RunningTotalSales] / SUM(DimProduct[TotalSales])
=IF( DimProduct[RunningPct] <= 0.7; "A"; IF( DimProduct[RunningPct] < =0.9;
"B"; "C";
) )
#sqlsat257#sqlsatveronaNovember 9th, 2013
Analisi di Pareto e l’analisi ABC
Se volessi vedere anche il numero di prodotti chegenerano quei fatturati uso la seguente misura
=COUNTROWS(DimProduct)
#sqlsat257#sqlsatveronaNovember 9th, 2013
Analisi di Pareto e l’analisi ABC
#sqlsat257#sqlsatveronaNovember 9th, 2013
Link and Book
PowerPivot http://www.powerpivot.com
SQLBI http://www.sqlbi.com
Libro di riferimento
#sqlsat257#sqlsatveronaNovember 9th, 2013
Q & A
#sqlsat257#sqlsatveronaNovember 9th, 2013
Thanks!
#sqlsat257#sqlsatverona