Obtener los cuartiles en un cubo Microsoft Analysys Services.
Solución: La función para calcular cuartiles no existe en MDX. Existen varias formas de calcularlos como puede leerse en este interesante articulo de ElectroVoid, pero la optima es usar una procedimiento almacenado SSAS.
Hay que desarrollarlo en un lenguaje .NET, en el articulo mencionado utilizan C#, yo aportó aquí el código VB.NET.
Imports Microsoft.AnalysisServices
Namespace Percentiles
Public Class Percentil
_
Public Shared Function Cuartil(ByVal conjunto As AdomdServer.Set, _
ByVal expr As AdomdServer.Expression, _
ByVal Qtile As Integer) As AdomdServer.MDXValue
If Qtile < 0 Or Qtile > 4 Then Throw New ArgumentOutOfRangeException(Qtile)
Dim valores = New List(Of Double)
For Each tupla In conjunto.Tuples
Dim mdxVal = expr.Calculate(tupla)
If mdxVal.ToChar <> ChrW(0) Then valores.Add(mdxVal.ToDouble)
Next
If valores.Count > 0 Then
valores.Sort()
Dim cuenta = valores.Count
If (Qtile = 4) OrElse (cuenta = 1) Then Return (AdomdServer.MDXValue.FromDouble(valores.Item(cuenta - 1)))
Dim porcentaje As Double = CDbl(Qtile) / 4.0
Dim qidx As Double = porcentaje * CDbl(cuenta - 1)
Dim qfloor = Math.Floor(qidx)
Dim qfrac = qidx - qfloor
Return AdomdServer.MDXValue.FromDouble( _
valores.Item(CInt(qfloor)) _
+ (qfrac * (valores.Item(CInt(qfloor + 1)) _
- valores.Item(CInt(qfloor)) _
)) _
)
Else
Return Nothing
End If
End Function
_
Public Shared Function CuartilOrdenado(ByVal conjunto As AdomdServer.Set, _
ByVal expr As AdomdServer.Expression, _
ByVal Qtile As Integer) As AdomdServer.MDXValue
'En esta versión la llamada debe realizarse con el conjunto ordenado y sin valores vacios
If Qtile < 0 Or Qtile > 4 Then Throw New ArgumentOutOfRangeException(Qtile)
Dim valores = New List(Of Double)
For Each tupla In conjunto.Tuples
Dim mdxVal = expr.Calculate(tupla)
valores.Add(mdxVal.ToDouble)
Next
If valores.Count > 0 Then
Dim cuenta = valores.Count
If (Qtile = 4) OrElse (cuenta = 1) Then Return (AdomdServer.MDXValue.FromDouble(valores.Item(cuenta - 1)))
Dim porcentaje As Double = CDbl(Qtile) / 4.0
Dim qidx As Double = porcentaje * CDbl(cuenta - 1)
Dim qfloor = Math.Floor(qidx)
Dim qfrac = qidx - qfloor
Return AdomdServer.MDXValue.FromDouble( _
valores.Item(CInt(qfloor)) _
+ (qfrac * (valores.Item(CInt(qfloor + 1)) _
- valores.Item(CInt(qfloor)) _
)) _
)
Else
Return Nothing
End If
End Function
End Class
End Namespace
Observad que he creado dos metodos, en el primero incluyo el ordenado y la eliminación de elementos vacios, en el segundo espero recibir el conjunto con estas tareas realizadas.percentiles.cuartilOrdenado(
ORDER(
NONEMPTY
(descendants([DimEmpresas].[Facturacion].currentmember, [DimEmpresas].[Facturacion].[Empresa])
,[Measures].[% A-1 VN Euros]
)
,[Measures].[% A-1 VN Euros]
,BASC
)
,[Measures].[% A-1 VN Euros]
,3)
Para desarrollar la aplicación instalar SSAS en la máquina de desarrollo y añadi una referencia a msmgdsrv.dll en C:\Archivos de programa\Microsoft SQL Server\MSAS10_50.MSSQLSERVER\OLAP\binLuego añadir el ensamblado al servidor SSAS, a la base de datos o al proyecto (ver msdn) Si alguien necesita la ddl que me lo diga.<(p>
No hay comentarios:
Publicar un comentario