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 PercentilObservad 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._ 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
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\bin
Luego 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>