in

UGISS Community

Il sito della community dello User Group Italiano di SQL Server

YEAR & YEAR-1

Last post 06-14-2007 14.31 by locuratropical. 4 replies.
Page 1 of 1 (5 items)
Sort Posts: Previous Next
  • 06-13-2007 17.33

    YEAR & YEAR-1

    Ciao a tutti.

    Spero di non chiedere una stupidaggine/ovvieta', ma io ci sto perdendo un pochino di tempo dietro...

     :-)

     Tramite BIDS ho creato un cubetto composto dalle tre classiche dimensioni (Tempo, Mercati, Prodotti) e da alcune misure (venduto, q.ta', ecc).

    Fin qui tutto ok, riesco a fare drill down, slice & dice, caffe' borghetti per tutti, ecc.

    Il problema che mi si pone e' che vorrei esporre, ad esempio per il venduto, sia la misura del periodo che prendo in esame (ad esempio il 2007) sia le informazioni della stessa misura per lo stesso periodo ma dell'anno precedente su due colonne affiancate. In questo modo lo "Sciur Manager" non fara' fatica a visualizzare immediatamente cosa "vendette" in quel periodo l'anno prima.

    Qualcuno di voi ha gia' brillantemente risolto il problema?

     RIBADISCO LE MIE SCUSE SE SI TRATTA DI UNA STRU@#@@#@@#@ATA...

    Ciao

    Axel aka LocuraTropical

     

    • Post Points: 20
  • 06-14-2007 0.51 In reply to

    • fdechirico
    • Top 25 Contributor
      Male
    • Joined on 05-15-2007
    • Milano
    • Posts 63
    • Points 720

    Re: YEAR & YEAR-1

    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".

    Francesco De Chirico
    SQL Server MCP, MCTS, MCITP, MCT
    http://community.ugiss.org/blogs/fdechirico/
    BI Architect @ Solid Quality Learning Italy - http://www.solidq.com
    • Post Points: 20
  • 06-14-2007 11.48 In reply to

    Re: YEAR & YEAR-1

    Ok, sto optando per il WIZARD.

    Premesso che:

    . la mia dimensione del tempo (che ho fantasiosamente chiamato CALENDARIO) ha dentro i seguenti attributi:
    DATE (Chiave)
    MONTH
    QUARTER
    YEAR

    e le seguenti due gerarchie:
    YEAR-QUARTER-MONTH
    YEAR-MONTH-DATE

    Quando vado a "wizardare" (tasto destro dal cubo scegliendo "Add Business Intelligence") e scelgo "Time Intelligence", mi chiede di scegliere su cosa lavorare.
    A quel punto decido che vorrei lavorare sulla gerarchia YEAR-MONTH-DATE e lui mi propone sostanzialmente tre tipologie di calcolo:
    _periodo_ TO DATE (che mi restituisce l'accumulato dall'inizio di _periodo_ )
    _periodo_ MOVING AVERAGE (che non fa quel che cerco io)
    _periodo_ OVER _periodo_ (differenze tra il periodo e quello precedente)

     Ergo, nessuno dei tre mi permette di avere la seconda colonna con quello che ho eventualmente (venduto/acquistato/ecc) nella stessa data l'anno prima.

    Idee/suggerimenti?

    Grazie in anticipo.

    Ale

    • Post Points: 20
  • 06-14-2007 12.56 In reply to

    • fdechirico
    • Top 25 Contributor
      Male
    • Joined on 05-15-2007
    • Milano
    • Posts 63
    • Points 720

    Re: YEAR & YEAR-1

    Ciao Ale,

    dovresti trovarti anche una "Year Over Year Growth" che ti fornisce la differenza rispetto all'anno precednte.

    A questo punto, manualmente, puoi modificare il codice generato per usare solo la funzione ParallelPeriod.

    Guarda questo esempio, questo è il codice inserito dal Wizard:

     

    /*

    Begin Time Intelligence script for the [Month].[ANNI] hierarchy.

    */

    Create Member

    CurrentCube.[Month].[ANNI Month Calculations].[Year Over Year Growth]

    As "NA" ;

    Scope(

    {

    [Measures].[PROBLEM COUNT]

    }

    ) ;

    // Year Over Year Growth

    (

    [Month].[ANNI Month Calculations].[Year Over Year Growth],

    [Month].[YEAR].[YEAR].Members ( 1 ) : Null,

    [Month].[Fact Data].Members

    ) =

    ( [Month].[ANNI Month Calculations].DefaultMember ) -

    ( [Month].[ANNI Month Calculations].DefaultMember,

    ParallelPeriod(

    [Month].[ANNI].[YEAR],

    1,

    [Month].[ANNI].CurrentMember

    )

    ) ;

    (

    [Month].[ANNI Month Calculations].[Year Over Year Growth],

    [Month].[YEAR].[YEAR].Members ( 0 ),

    [Month].[Fact Data].Members

    ) = Null ;

    End Scope ;

    /*

    End Time Intelligence script for the [Month].[ANNI] hierarchy.

    */

     

    Questo è quello modificato :

    /*

      Begin Time Intelligence script for the [Month].[ANNI] hierarchy.

    */

     

    Create Member

      CurrentCube.[Month].[ANNI Month Calculations].[Last Year Value]

      As "NA" ;

     

     

    Scope(

           {

             [Measures].[PROBLEM COUNT]

           }

    ) ;

     

    // Last Year Value

      (

          [Month].[ANNI Month Calculations].[Last Year Value],

        [Month].[YEAR].[YEAR].Members ( 1 ) : Null,

          [Month].[Fact Data].Members

      ) =     

     

      ( [Month].[ANNI Month Calculations].DefaultMember,

        ParallelPeriod(

                        [Month].[ANNI].[YEAR],

                        1,

                        [Month].[ANNI].CurrentMember

        )

      ) ;

     

      (

        [Month].[ANNI Month Calculations].[Last Year Value],

        [Month].[YEAR].[YEAR].Members ( 0 ),

          [Month].[Fact Data].Members

      ) = Null ;

     

     

    End Scope ;

     

    /*

      End Time Intelligence script for the [Month].[ANNI] hierarchy.

    */

     

    In questo modo mantieni la logica di funzionamento del wizard (cioè una shell hierarchy nella dimensione temporale)

    Al momento non posso fare prove, fammi sapere se questa soluzione risolve il tuo problema.

    Altra strada è quella di creare membri calcolati "ad-hoc" nel cubo, oppure seguire l'esempio che ti ho segnalato nel post precedente.

    Francesco De Chirico
    SQL Server MCP, MCTS, MCITP, MCT
    http://community.ugiss.org/blogs/fdechirico/
    BI Architect @ Solid Quality Learning Italy - http://www.solidq.com
    • Post Points: 20
  • 06-14-2007 14.31 In reply to

    Re: YEAR & YEAR-1

    GRANDE!

    Ho ottenuto quello che volevo!
    Questo vuol dire che devo mettermi a studiare un minimo di MDX, visto che ora, alla luce di quello che e' la soluzione, la trovo cosi' semplice che non riesco a non ROSICARE! ;-)

    Grazie infinite per l'aiuto.

    Ciao

    Ale

    • Post Points: 5
Page 1 of 1 (5 items)
(C) 2007 User Group Italiano di SQL Server