Archivio per la categoria MDX

SSAS Count distinct with Null

Interessante e utile articolo, per ovviare ad il problema del count distinct in analysis services quando vi è un membro con valore Null.
Esempio: effettuare count distinct del campo cliente.

CLIENTE
A
A
B
C
NULL

Risultato atteso: 3
Risultato ottenuto: 4

Come risolvere il problema ?
leggi l articolo

Leggi il seguito di questo post »

Annunci

, , ,

1 Commento

SQL, MDX E DAX alla ricerca del RANK perduto.

Questa è la breve storia di tre signori di epoche diverse con la medesima esigenza, ritrovare il Rank perduto.
SQL è un signore di 38 anni nato in un laboratorio IBM, e possiede la grande dote di saper interrogare

MDX è il cugino di SQL, nasce nel 1997 ed era un Teenager con ottime prospettive, e una delle sue caratteristiche è quella di saper
manipolare

DAX è il più giovane dei tre non ha neanche 5 anni e deve ancora farsi le ossa, ma è dotato di grande memoria

Un giorno di Settembre SQL, MDX e DAX si trovano nel bel mezzo di una base di dati gigantesca piena di esseri strani chiamati bit.
C’erano bit di tutte le forme e di tutte le dimensioni che infastidivano i nostri amici.

SQL, il più esperto dei 3 disse:
Select
Bit, Forma, Grandezza
, RANK() OVER (PARTITION BY Forma ORDER BY Grandezza DESC) AS Rank
from GrandeBaseDati

ovvero

“dobbiamo assegnare un rango di grandezza per ogni forma. Solo in questo modo saremo in grado di difenderci !!!”.

L’idea era giusta ma la GrandeBaseDati non voleva cedere all’interrogazione del nostro SQL e dopo 3 ore ancora non si era avuta nessuna risposta.

Il giovane MDX decise di entrare in azione e disse:
WITH MEMBER [Measures].[Rank] AS
RANK([DIM_Forme].[Forma].CurrentMember, ORDER([DIM_Forme].[Forma].[Forma].MEMBERS, [Measures].[Grandezza], BDESC))
SELECT
[Measures].[Rank] ON 0
,[DIM_Forme].[Forma].[Forma].MEMBERS on 1
FROM [GrandeBasiDati]

“fatemi manipolare un po questa GrandeBaseDati, la mettiamo in un Cubo, gli facciamo fare un po’ di aggregazioni e vedrete che otterremo la risposta che ci serve!”

Anche in questo caso l’idea poteva avere successo ma il tempo passava inesorabile e le risposte non arrivavano.

L’infante DAX si fece avanti e disse:
Rank: = RANKX (ALLEXCEPT(Bit;Bit[Forma]);[Grandezza])

ovvero

“Non serve aspettare le risposte da questo mostro, lui non ce le darà mai, dobbiamo solo osservare e memorizzare, le risposte arriveranno da sole”.

SQL e MDX si guardarono perplessi ma dopo pochi secondi avevano tutto chiaro e vedevano tutte le forme dei bit in ordine di grandezza.
Riuscirono cosi a schivare quelle più grandi e quelle più insidiose e finalemente uscirono dalla GrandeBaseDati.

MORALE: puoi saper interrogare, puoi saper manipolare ma se non hai un briciolo di memoria non avrai mai tutte le risposte nel tempo necessario.

7 commenti

Creazione di Set personalizzati – Named Set

Nella realizzazione di reportistica capita spesso di dover organizzare i dati in maniera diversa dagli attributi o dalle gerarchie di riferimento nel cubo di Analysis Services.
Per questo motivo il inguaggio MDX mette a disposizione la possibilità di creare dei set personalizzati.

Questi set di dati possono essere realizzati direttamente sul cubo e quindi utilizzati sia nei report di Reporting Services che in Excel 2010 oppure possono essere creati direttamente nel “dataset” del report.

Nell’esempio proposto bisogna realizzare un report come quello in figura:


Le voci presenti in colonna  raggruppano gli attributi della data di produzione secondo le voci presenti in Legenda.

Step 1 – Creazione dei Membri calcolati presenti in colonna.

WITH

— IDENTIFICA IL TUTTI I MESI ANTECEDENTI A MESE-1
MEMBER [Periodo Produzione].[Mese].[Oltre M-1] AS
 SUM({[Periodo Produzione].[Mese].&[200001]:STRTOMEMBER(“[Periodo Produzione].[Mese].&[” + CStr(year(Now())) + Right(“000” + Cstr(month(Now())-2),2) + “]”)})

— IDENTIFICA IL MESE PRECEDENTE
MEMBER [Periodo Produzione].[Mese].[M-1] AS
SUM({STRTOMEMBER(“[Periodo Produzione].[Mese].&[” + CStr(year(Now())) + Right(“000” + Cstr(month(Now())-1),2) + “]”)})

— IDENTIFICA IL MESE CORRENTE
MEMBER [Periodo Produzione].[Mese].[MC] AS
 SUM({STRTOMEMBER(“[Periodo Produzione].[Mese].&[” + CStr(year(Now())) + Right(“000” + Cstr(month(Now())),2) + “]”)})

— IDENTIFICA IL MESE PROSSIMO
MEMBER [Periodo Produzione].[Mese].[M+1] AS
SUM({STRTOMEMBER(“[Periodo Produzione].[Mese].&[” + CStr(year(Now())) + Right(“000” + Cstr(month(Now())+1),2) + “]”)})

— IDENTIFICA IL TUTTI I MESI Oltre A MESE+1
MEMBER [Periodo Produzione].[Mese].[Oltre M+1] AS
SUM({STRTOMEMBER(“[Periodo Produzione].[Mese].&[” + CStr(year(Now())) + Right(“000” + Cstr(month(Now())+2),2) + “]”):[Periodo Produzione].[Mese].&[201309]})

Step 2 – Creiamo un membro di ordinamento per l’esposizione nel report.

CASE
 WHEN [Periodo Produzione].[Mese].currentmember = [Periodo Produzione].[Mese].[Oltre M-1] THEN 1
 WHEN [Periodo Produzione].[Mese].currentmember = [Periodo Produzione].[Mese].[M-1] THEN 2
 WHEN [Periodo Produzione].[Mese].currentmember = [Periodo Produzione].[Mese].[MC] THEN 3
 when [Periodo Produzione].[Mese].currentmember = [Periodo Produzione].[Mese].[M+1] THEN 4
 WHEN [Periodo Produzione].[Mese].currentmember = [Periodo Produzione].[Mese].[Oltre M+1] THEN 5
END

Step 3 – Creazione del Named Set

SET MeseProduzione as
{[Oltre M-1], [M-1], [MC], [M+1] , [Oltre M+1]}

Step 4 – Query MDX Finale

SELECT
 NON EMPTY {[Measures].[NomeMisura],OrdinamentoMese} ON COLUMNS,
 NON EMPTY {([DimSocieta].[Societa].[Societa].ALLMEMBERS * MeseProduzione)} ON ROWS
FROM [NomeCubo]

, , ,

Lascia un commento

MDX – Misura di Forecast

Col seguente codice è possibile creare una misura che riporti il valore dal giorno selezionato  fino alla fine dell’anno corrente.
 
In questo caso l’attributo “indic” è composto da AAAAMMGG  es. 20111231 come fine anno.
 
WITH MEMBER [Measures].[Forecast] As
SUM({[DimTempo].[Indice].currentmember : STRTOMEMBER(“[DimTempo].[Indice].&[” + CStr(Year(Now())) + “1231]”)}
   , [Measures].[NomeMisura]
   )
Select [Measures].[Forecast] on columns,
[DimTempo].[Indice].[Indice] on rows
from [NomeCubo]

, , ,

Lascia un commento

MDX – CURRENT YEAR

Se abbiamo bisogno di una query MDX che visualizzi solo i dati dell’anno corrente possiamo costruire il membro con questa semplice sintassi:
(STRTOMEMBER(“[Periodo].[Anno].[Anno].&[” + CStr(year(Now())) + “]”))

2 commenti

Utilizzo del LIKE in MDX

A differenza del linguaggio SQL, non esiste la funzione LIKE in MDX.
Per ottenere lo stesso risultato in MDX bisogno utlizzare questo codice:

FILTER([Nome Dimensione].[NomeDimensione].Members,
LEFT([Nome Dimensione].[NomeDimensione].CurrentMember.Name, NumeroDiCaratteri) = “Parola”)

Es. Tutti i Clienti che iniziano per “Vari”

FILTER([Dim Clienti].[Dim Clienti].Members, LEFT([Dim Clienti].[Dim Clienti].CurrentMember.Name, 4) = “Vari”)

1 Commento

Misura di Deafult Cubo SSAS

Ogni cubo ha una misura di default impostata automaticamente.
 
Per sapere qual’è eseguire questo script:
 

WITH
MEMBER [Measures].[dMemberName] AS
[Measures].DefaultMember.Member_Name
SELECT{
[Measures].[dMemberName]}
ON 0 FROM [NomeCubo]

Per impostare una misura come misura di default, inserire questo script all’interno delle misure calcolate:

ALTER CUBE CURRENTCUBE UPDATE DIMENSION Measures, DEFAULT_MEMBER=[Measures].[Nome Misura]

Lascia un commento