Per ottenere quello che vuoi ci sono molte strade e stabilire quale sia quella giusta/migliore non sempre è semplice non conoscendo tutti i particolari del tuo caso specifico.
Senza entrare nel dettaglio delle infinite possibilità per ottenere il risultato finale e sintetizzando molto, la tua esigenza potrebbe ricadere in una di queste due possibili situazioni:
1) Esporre il valore all’interno di una query MDX (estemporanea o utilizzata in un report)
2) Esporre il valore all’interno del cubo (e quindi rendendolo riutilizzabile ovunque)
Vediamo il primo caso.
Fondamentalmente si tratta di utilizzare il linguaggio MDX per ottenere il valore richiesto. Il linguaggio MDX mette a disposizione parecchie funzioni per ottenere questo risultato sfruttando una delle sue caratteristiche peculiari, ossia quella di consentire la navigazione nei metadati che definiscono le strutture multidimensionali. Tra le tante, per esempio “PrevMember“,“ Lag()“,“Cousin“, ecc.
In particolare esiste la funzione "ParallelPeriod" che fa proprio al caso tuo.
La seguente query MDX su "Adventure Works DW"
SELECT {[Measures].[Internet Sales Amount],[Measures].[Internet Order Quantity]} ON ROWS,
{[Date].[Calendar Year].&[2004],
ParallelPeriod([Date].[Calendar Year].[Calendar Year], 1, [Date].[Calendar Year].&[2004])} ON COLUMNS
FROM [Adventure Works]
restituisce il valore delle misure (in questo caso due) riferite all'anno 2004 ed all'anno 2003 (recuperato attraverso la funzione ParallelPeriod). In questo modo siamo svincolati dalla/e misure utilizzate (nel senso che qualsiasi si utiilizzi il risultato sarà corretto), ma non siamo svincolati dalle date in quanto se volessimo ottenere il dato dell’anno precedente rispetto al 2003 dovremmo modificare
ParallelPeriod([Date].[Calendar Year].[Calendar Year], 1, [Date].[Calendar Year].&[2004])
In
ParallelPeriod([Date].[Calendar Year].[Calendar Year], 1, [Date].[Calendar Year].&[2003])
Possiamo “svincolarci” dalla definizione puntuale delle date pagando lo scotto di dovere definire un membro calcolato per ogni misura che intendiamo utilizzare:
WITH MEMBER [Measures].[Internet Sales Amount Previous Year] AS
Aggregate(ParallelPeriod([Date].[Calendar Year].[Calendar Year], 1, [Date].[Calendar Year].CurrentMember),[Measures].[Internet Sales Amount])
SELECT {[Measures].[Internet Sales Amount],[Measures].[Internet Sales Amount Previous Year]} ON ROWS,
{[Date].[Calendar Year].AllMembers} ON COLUMNS
FROM [Adventure Works]
Vediamo il caso due.
La modalità più semplice è sicuramente quella di utilizzare il “Business Intelligence Wizard” che consente di creare velocemente i principali membri calcolati sulla dimensione temporale. Questa modalità (che decisamente semplifica la vita), presenta però alcune controindicazioni. Prima fra tutte occorre che la dimensione temporale sia definita correttamente rispetto alle metriche di Analysis Services. Ciò implica che ad ogni attributo venga assegnata la corretta tipologia (proprietà “Type” dell’attributo), che le relazioni tra attributi siano correttamente definite, ecc.
Un’altra possibiltà è quella di creare una soluzione “custom” all’interno del cubo scrivendo l’opportuno codice MDX all’interno dei “Calculations”. Questa soluzione può risultare però molto impegnativa perchè occorre garantire che i membri calcolati (nel tuo caso “il membro calcolato”) funzionino in qualsiasi circostanza, o meglio, che restituiscano dei dati consistenti in qualunque query vegano utilizzati. Questo requisito può diventare non semplice da garantire, soprattutto in presenza di cubi complessi con gerarchie temporali articolate e aggregazioni a diversi livelli di granularità.
In ogni caso, solitamente per questo tipo di implementazioni viene creata una dimensione “fittizia” (Shell dimension) che svolge la funzione di mero contenitore dei membri calcolati (che è poi quello che fa il “Business Intelligence Wizard”).
Per familiarizzare con l’uso dell’MDX puoi consultare il BOL (in particolare alle voci "ParallelPeriod" ,“PrevMember“,“ Lag()“, “Cousin“) o la “bibbia”. Ti segnalo inoltre questo articolo in cui viene proposta una alternativa “custom” all’uso del wizard, questa lezione di William Pearson e questo post in cui Mosha Pasumansky approfondisce l’argomento"ParallelPeriod".