Due strumenti, due momenti di calcolo

In un semantic model di Power BI, DAX ti mette a disposizione due oggetti che sembrano intercambiabili ma vivono in mondi diversi: le calculated columns e le measures. Capire quando e dove vengono valutati è la chiave per scegliere correttamente, ottimizzare la RAM e superare gli scenari d’esame.

Calculated columns: valutate al refresh, materializzate

Una calculated column viene calcolata una volta al data refresh e il suo risultato viene materializzato riga per riga dentro il motore colonnare VertiPaq. Da quel momento occupa storage esattamente come una colonna importata, e la sua compressione dipende dalla cardinalità: pochi valori distinti = ottima compressione, alta cardinalità (es. una colonna con importi calcolati unici) = tabella gonfia e modello lento.

Le calculated columns operano in row context: ogni riga “vede” i propri valori, quindi puoi scrivere espressioni come Prezzo * Quantità senza funzioni di aggregazione. Non reagiscono ai filtri della visual: il valore è fisso, congelato al refresh.

Le usi quando ti serve un valore statico per riga da impiegare come:

  • chiave di relazione tra tabelle (una colonna concatenata per una relazione composta)
  • campo da mettere in uno slicer, su un asse o in una gerarchia
  • categoria di raggruppamento (es. una fascia “Basso/Medio/Alto” derivata da un valore)

Measures: valutate a query time, zero storage

Una measure non memorizza nulla: viene valutata dinamicamente a query time, ogni volta che l’utente interagisce con un visual, e opera in filter context. Il risultato dipende dai filtri attivi (slicer, righe/colonne della matrice, cross-filtering). Per questo SUM, AVERAGE, DIVIDE e le funzioni di aggregazione stanno naturalmente in una measure.

Vantaggi rispetto alla colonna calcolata:

  • nessun costo di storage e nessun impatto sulla dimensione del modello
  • risultato contestuale, che si ricalcola secondo i filtri
  • riuso: una measure può richiamarne un’altra, costruendo logiche a strati (es. Margine % che riusa [Ricavi] e [Costi])

Il rovescio della medaglia è che il costo si sposta sul motore formula engine in fase di query: measure scritte male possono rallentare i report interattivi.

La regola pratica

Il principio da tenere a mente per l’esame è netto: preferisci sempre una measure, e usa una calculated column solo quando il valore deve esistere fisicamente per riga — cioè quando ti serve come chiave di relazione, come campo per uno slicer/asse, o come attributo di raggruppamento che non puoi ottenere dinamicamente.

Se il tuo obiettivo è aggregare (somme, medie, conteggi, percentuali che reagiscono ai filtri), la risposta è measure. Se devi filtrare, raggruppare o mettere in relazione, allora valuta la colonna. In molti casi, ciò che sembra richiedere una colonna calcolata si risolve meglio a monte in Power Query (colonna materializzata più comprimibile) o direttamente nella source.

Implicit vs explicit measures

Quando trascini un campo numerico su un visual e Power BI applica in automatico Sum o Count, stai usando una implicit measure: non esiste come oggetto DAX, è solo un’aggregazione al volo del report.

Le explicit measures, che scrivi tu con DAX, sono sempre da preferire perché offrono:

  • controllo totale sulla logica (gestione di DIVIDE per evitare divisioni per zero, filtri con CALCULATE)
  • riuso in più visual e come base per altre measures
  • formattazione e naming centralizzati, indipendenti dal campo sorgente
  • compatibilità con scenari avanzati (calculation groups, time intelligence)

Best practice moderna: disabilitare le implicit measures nel modello e nascondere le colonne numeriche fact, così gli autori dei report sono obbligati a usare measure esplicite e coerenti.

Trappole tipiche d’esame

  • Scenario: hai bisogno di un totale vendite che cambi in base allo slicer Anno → measure con SUM, non una calculated column (la colonna sarebbe statica e sprecherebbe memoria).
  • Scenario: devi creare una relazione tra due tabelle su una chiave composta → calculated column che concatena i campi (una measure non può materializzare la chiave).
  • Scenario: modello troppo grande/lento dopo aver aggiunto Prezzo * Quantità come colonna ad alta cardinalità → sposta il calcolo in una measure o materializzalo in Power Query, non lasciarlo come calculated column.
  • Scenario: serve un campo fascia (Basso/Medio/Alto) da usare in uno slicercalculated column, perché una measure non può essere posta su un asse o in un filtro come attributo.
  • Scenario: più visual mostrano lo stesso KPI con logica ripetuta e incoerente → sostituisci le implicit measures con una explicit measure riutilizzabile e centralizzata.