Diese Präsentation wurde erfolgreich gemeldet.
Die SlideShare-Präsentation wird heruntergeladen. ×

Sql saturday 829_decalogo_powerbi

Anzeige
Anzeige
Anzeige
Anzeige
Anzeige
Anzeige
Anzeige
Anzeige
Anzeige
Anzeige
Wird geladen in …3
×

Hier ansehen

1 von 40 Anzeige
Anzeige

Weitere Verwandte Inhalte

Anzeige

Aktuellste (20)

Anzeige

Sql saturday 829_decalogo_powerbi

  1. 1. #sqlsat Progetto Power BI – Un Decalogo Lorenzo Vercellati
  2. 2. Speaker  Business Intelligence Specialist @ SolidQ  Data Visualization Addicted  Speaker al SQL Saturday  DIAD Trainer  PBIUG Milan Administrator  @supergimi  lorenzovercellati
  3. 3. Agenda  Centralizzare la DataSource  A ciascuno la sua dieta  Lavoriamo solo su misure  Calendar & Time Dimension from scratch  Filters Applied  A ciascuno il suo visual  Custom Topojson  Tips, Tricks & Tools  Buone letture
  4. 4. Il Progetto PowerBI
  5. 5. Il Progetto BI DataSource ETL Flow Visuals Data Model
  6. 6. Il Progetto PowerBI DataSource ETL Flow Visuals Data Model
  7. 7. Centralizzare e Parametrizzare la DataSource
  8. 8. Centralizzare la DataSource Data Source Data Set Data Set Data Source Data Source Data Set Data Set
  9. 9. A Ciascuno la sua dieta
  10. 10. Vertipaq Storage Tab XXX XXX YYY ZZZ AAA AAA AAA Diz XXX YYY ZZZ AAA Tab XX.A XX.B YY.A ZZ.A ZZ.C XX.C YY.C Diz XX.A XX.B YY.A ZZ.A ZZ.C XX.C YY.C
  11. 11. Togliere ai Ricchi… Tab XX A XX B YY A ZZ A ZZ C XX C YY C Diz XX YY ZZ XX YY Tab XX XX YY ZZ ZZ XX YY Tab A B A A C C C Diz A B A C Tab XX.A XX.B YY.A ZZ.A ZZ.C XX.C YY.C
  12. 12. …e dare ai Poveri Se non abbiamo Longitudine e Latitudine dobbiamo affidarci ai nomi dei luoghi geografici! I casi di omonimia geografica sono tantissimi e i servizi di geolocalizzazione di Bing non sempre rispondono a dovere. Più informazioni gli diamo, più facile sarà il loro lavoro e più precise saranno le risposte. Categorizziamo sempre le colonne geografiche.
  13. 13. Lavoriamo solo su misura
  14. 14. Lavoriamo solo su Misura Per il semplice fatto che Power BI ce le propone come misure, non significa che dobbiamo usare le colonne numeriche come misure nei visual!
  15. 15. Lavoriamo solo su Misura  Creo le misure Base a partire dalle colonne numeriche ColValue TotaleValue TotaleValue PreviousYear Saldo vs PreviousYear % vs PreviousYear  Creo le misure Complesse a partire dalle misure Base  Nascondo le colonne
  16. 16. Calendar and Time Dimension from scratch
  17. 17. All You Need is Date Dim
  18. 18. All You Need is Date Dim let StartDate = #date(StartYear,12,1), // EndDate = #date(EndYear,12,31), EndDate = Date.From(DateTime.LocalNow()), NumberOfDays = Duration.Days( EndDate - StartDate ), Dates = List.Dates(StartDate, NumberOfDays+1, #duration(1,0,0,0)), #"Converted to Table" = Table.FromList(Dates, Splitter.SplitByNothing(), null, null, ExtraValues.Error), #"Renamed Columns" = Table.RenameColumns(#"Converted to Table",{{"Column1", "FullDateAlternateKey"}}), #"Changed Type" = Table.TransformColumnTypes(#"Renamed Columns",{{"FullDateAlternateKey", type date}}), #"Inserted Year" = Table.AddColumn(#"Changed Type", "Year", each Date.Year([FullDateAlternateKey]), type number), #"Inserted Month" = Table.AddColumn(#"Inserted Year", "Month Number", each Date.Month([FullDateAlternateKey]), type number), #"Inserted Month Name" = Table.AddColumn(#"Inserted Month", "Month", each Date.MonthName([FullDateAlternateKey]), type text), #"Inserted Quarter" = Table.AddColumn(#"Inserted Month Name", "Quarter Number", each Date.QuarterOfYear([FullDateAlternateKey]), type number), #"Inserted Week of Year" = Table.AddColumn(#"Inserted Quarter", "Week of Year", each Date.WeekOfYear([FullDateAlternateKey]), type number), #"Inserted Week of Month" = Table.AddColumn(#"Inserted Week of Year", "Week of Month", each Date.WeekOfMonth([FullDateAlternateKey]), type number), #"Inserted Day" = Table.AddColumn(#"Inserted Week of Month", "Day", each Date.Day([FullDateAlternateKey]), type number), #"Inserted Day of Week" = Table.AddColumn(#"Inserted Day", "Day of Week Number", each Date.DayOfWeek([FullDateAlternateKey],1), type number), #"Inserted Day of Year" = Table.AddColumn(#"Inserted Day of Week", "Day of Year", each Date.DayOfYear([FullDateAlternateKey]), type number), #"Inserted Day Name" = Table.AddColumn(#"Inserted Day of Year", "Day of Week", each Date.DayOfWeekName([FullDateAlternateKey]), type text), #"Inserted Year Month" = Table.AddColumn(#"Inserted Day Name", "Year Month Number", each [Year] * 100 + [Month Number], type number), #"Inserted Year Month Name" = Table.AddColumn(#"Inserted Year Month", "Year Month", each Text.Combine({[Month], " ", Text.From([Year], "en-US")}), type text), #"Inserted Year Quarter" = Table.AddColumn(#"Inserted Year Month Name", "Year Quarter Number", each [Year] * 10 + [Quarter Number], type number), #"Inserted Quarter Name" = Table.AddColumn(#"Inserted Year Quarter", "Quarter", each Text.Combine({"Q", Text.From([Quarter Number], "en-US")}), type text), #"Inserted Year Quarter Name" = Table.AddColumn(#"Inserted Quarter Name", "Year Quarter", each Text.Combine({[Quarter], " ", Text.From([Year], "en-US")}), type text), #"Inserted Year Week" = Table.AddColumn(#"Inserted Year Quarter Name", "Year Week Number", each [Year] * 100 + [Week of Year], type number), #"Inserted Year Week Name" = Table.AddColumn(#"Inserted Year Week", "Year Week", each Text.Combine({"Week", " ", Text.From([Week of Year], "en-US"), " ", Text.From([Year], "en-US")}), type text), #"Renamed Columns1" = Table.RenameColumns(#"Inserted Year Week Name",{{"FullDateAlternateKey", "Date"}}) in #"Renamed Columns1"
  19. 19. All You Need is Date Dim let SecondCount = 86400, Source = List.Times(#time(0, 0, 0),SecondCount, #duration(0,0,0,1)), TableFromList = Table.FromList(Source, Splitter.SplitByNothing()), ChangedType = Table.TransformColumnTypes(TableFromList,{{"Column1", type time}}), RenamedColumns = Table.RenameColumns(ChangedType,{{"Column1", "Time"}}), InsertHour = Table.AddColumn(RenamedColumns, "Hour", each Time.StartOfHour([Time])), InsertMinute = Table.AddColumn(InsertHour, "Minute", each Time.Minute([Time])), ChangedTypeHour = Table.TransformColumnTypes(InsertMinute,{{"Hour", type time}}), InsertQuarterHour = Table.AddColumn(ChangedTypeHour, "Quarter Hour", each if [Minute]<15 then [Hour] else if [Minute] < 30 then Value.Add([Hour],#duration(0,0,15, 0)) else if [Minute] < 45 then Value.Add([Hour],#duration(0,0,30, 0)) else Value.Add([Hour],#duration(0,0,45, 0))), ChangedTypeQtrHr = Table.TransformColumnTypes(InsertQuarterHour,{{"Quarter Hour", type time}}), ReorderedColumns = Table.ReorderColumns(ChangedTypeQtrHr,{"Time", "Hour", "Quarter Hour", "Minute"}), InsertHourNumber = Table.AddColumn(ReorderedColumns, "Hour Number", each Time.Hour([Time])), NextHour = Table.AddColumn(InsertHourNumber, "Next Hour", each Value.Add([Hour],#duration(0,1,0, 0))), NextQuarterHour = Table.AddColumn(NextHour, "Next Quarter Hour", each Value.Add([Quarter Hour],#duration(0,0,15, 0))), InsertPeriod = Table.AddColumn(NextQuarterHour, "Period of Day", each if [Hour Number] >= 0 and [Hour Number] < 4 then "After Midnight" else if [Hour Number] >= 4 and [Hour Number] < 8 then "Early Morning" else if [Hour Number] >= 8 and [Hour Number] < 12 then "Late Morning" else if [Hour Number] >= 12 and [Hour Number] < 16 then "Afternoon" else if [Hour Number] >= 16 and [Hour Number] < 20 then "Evening" else "Late Night"), InsertPeriodSort = Table.AddColumn(InsertPeriod, "PeriodSort", each if [Hour Number] >= 0 and [Hour Number] < 4 then 0 else if [Hour Number] >= 4 and [Hour Number] < 8 then 1 else if [Hour Number] >= 8 and [Hour Number] < 12 then 2 else if [Hour Number] >= 12 and [Hour Number] < 16 then 3 else if [Hour Number] >= 16 and [Hour Number] < 20 then 4 else 5), InsertTimeKey = Table.AddColumn(InsertPeriodSort, "TimeKey", each Time.ToText([Time], "HHmm"), type text) in InsertTimeKey
  20. 20. Applied Filters
  21. 21. Applied Filters: un po’ di Chiarezza
  22. 22. Applied Filters: una Nuova Frontiera From: https://www.sqlbi.com/articles/displaying-filter-context-in-power-bi-tooltips/
  23. 23. A ciascuno il suo Visual
  24. 24. Cleveland and McGill
  25. 25. Anche l’occhio vuole la sua parte… L’occhio umano non è fatto per misurare gli angoli ma lunghezze e distanze. (cit. Alberto Cario, L’Arte Funzionale)
  26. 26. Tools
  27. 27. DAX Studio
  28. 28. Vertipaq Analyzer
  29. 29. Power BI Helper
  30. 30. Tips
  31. 31. M Helper = #shared
  32. 32. Power Query Alert PowEr qUeRy è CaSe sENsItivE
  33. 33. PowerBi Dataflows I dataflows sono dataset condivisi? Per i dataflows serve Premium Storage? Posso combinare query su dataflows senza Premium Storage? NO! NO! NO… …Anzi SI!
  34. 34. Tricks
  35. 35. 0 12 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 20 21 22 23 24 25 26 27 28 30 31 33 34 35 36 37 38 39 40 41 42 43 4 4 45 46 47 49 51 52 53 54 80 78 79 85 76 77 86 Customizzare Topojson Se non hai una mappa da convertire in topojson Se non hai alternative (QGIS), puoi sempre editare manualmente il file topojson che generata la mappa Topojson è un sottotipo del geojson file type La struttura di un Topojson consistse in: Una lista di arcs (segmenti) Una lista di oggetti (poligoni) definiti da una sequenza ordinata e chiusa di segmenti
  36. 36. 0 12 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 20 21 22 23 24 25 26 27 28 30 31 33 34 35 36 37 38 39 40 41 42 43 4 4 45 46 47 49 51 52 53 54 80 78 79 85 76 77 86 Customizzare Topojson Ogni Arc è definito da un entry point e da una sequenza di punti. Ogni Arc ha una direzione definita Gli oggetti definiti da un arc con direzione opporta sono referenziati come –1 * (arc + 1) 76 -77
  37. 37. Bibliografia
  38. 38. Buone Letture PowerQuery Chriss Webb: https://blog.crossjoin.co.uk/ DAX SQLBI: https://www.sqlbi.com/articles/ PowerBI Reza Rad: http://radacad.com/blog Guy in a Cube: https://www.youtube.com/channel/UCFp1vaKzpfvoGai0vE5VJ0w Dataflows BI Polar: https://ssbipolar.com/2018/10/23/dataflows-in-power-bi/
  39. 39. Grazie!

×