Рассчитать процентили в SSRS - PullRequest
2 голосов
/ 07 мая 2019

Нам нужно рассчитать процентиль (95-й и 99-й) в отчете SSRS на основе общего набора данных, который возвращает агрегированные данные с 15-минутным интервалом.Процент должен быть для дня в целом, но для контракта.

Для аргументов, скажем, это наши данные:

select
    'Test' as [ContractName],
    1 as [Value]

union all

select
    'Test' as [ContractName],
    3 as [Value]

union all

select
    'Test' as [ContractName],
    4 as [Value]

union all

select
    'Test' as [ContractName],
    6 as [Value]

union all

select
    'Test' as [ContractName],
    7 as [Value]

union all

select
    'Test' as [ContractName],
    36 as [Value]

union all

select
    'Test' as [ContractName],
    56 as [Value]

union all

select
    'Test' as [ContractName],
    798 as [Value]

union all

select
    'Test' as [ContractName],
    324 as [Value]

union all

select
    'Test' as [ContractName],
    456 as [Value]

union all

select
    'Test' as [ContractName],
    657 as [Value]

union all

select
    'Test' as [ContractName],
    658 as [Value]

Это почти отсортировано (это было, когдаЯ создал его), но сами данные не были бы в реальном приложении.

Мне нужно иметь возможность получить процентиль из этого набора данных без изменения SQL, так как это общий набор данных, используемый для контрактной отчетностии не может быть изменено.Общий набор данных используется для обеспечения согласованности всего набора отчетов.Поэтому решение должно быть в таблице в итоговом отчете.

Я посмотрел на выражение SSRS - запрос из набора данных с группой и заметил, что он имеет то же основное использование, что иthis Найдите медиану вычисляемого поля в SSRS 2012 , которое взято из https://blogs.msdn.microsoft.com/robertbruckner/2008/07/21/using-group-variables-in-reporting-services-2008-for-custom-aggregation/ и требует наличия ряда скрытых строк и групповых переменных, которые нелегко поддерживать / редактировать позднее.

1 Ответ

3 голосов
/ 07 мая 2019

В отчет может быть добавлен следующий пользовательский код:

Public Shared Function Centile(ByVal items As Object(), ByVal k As Decimal) As Decimal
    If items Is Nothing Then
        Return Nothing
    End If

    Dim counter as Decimal = items.Length
    If counter = 0 Then
        Return 0
    End If

    System.Array.Sort(items)

    Dim Position As Decimal = (k * (counter - 1))

    Dim FirstIndex As Integer = Floor(Position)
    Dim SecondIndex As Integer = Ceiling(Position)

    Dim Remainder As Decimal = Position - FirstIndex

    Dim FirstValue As Integer = items(FirstIndex)
    Dim SecondValue As Integer = items(SecondIndex)


    Return (FirstValue + (Remainder * (SecondValue - FirstValue)))

End Function

, который можно вызвать с помощью lookupset() в выражении, подобном следующему:

=Code.Centile(lookupset(Fields!ContractName.Value, Fields!ContractName.Value, Fields!Value.Value, "DS_Centile_LKP"), 0.95)

Это вызывает обратный вызовна себя, чтобы получить значения из того же набора данных, глядя на поле ContractName.lookupset() возвращает массив, который будет отсортирован в этой функции, вместо того, чтобы иметь переменные и все в одном месте - это простая функция в текстовом поле tablix, где отображается значение.Он также позволяет использовать разные значения, для которых вы хотите использовать процентиль - в приведенном выше примере он 95-й, поэтому 0,95.

...