Медиана и 95-й процентиль в SQL Server 2008?- NHS сообщает о требовании - PullRequest
0 голосов
/ 05 июля 2011

Я пытался выяснить 95-й процентиль и медиану встроенной функции в SQL Server 2008, но я не знаю, почему MS не поддерживает их, действительно раздражает ... Наши отчеты о рабочих местах очень сложны и нуждаются в прямомФункция пересылки или может быть DLL-файл, который я мог бы собрать с сервером SQL, чтобы использовать его как обычную функцию.

может любой совет.Заранее спасибо.

Реагрдс Али

Ответы [ 4 ]

1 голос
/ 05 июля 2011

Есть NTILE функция и для MEDIAN прочитайте это .

0 голосов
/ 03 июня 2013

Вы можете создать DLL в Visual Studio, чтобы сделать это, создав пользовательскую функцию агрегирования для использования в SQL Server.Для этого создайте новый проект Visual Studio и установите целевую платформу на .NET 3.5 (это для SQL 2008, она может отличаться в SQL 2012).Затем создайте файл класса и вставьте следующий код или эквивалент C #.

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

Этот процесс позволяет пользователю ввести любой процентиль для запроса.Запрос будет выглядеть следующим образом: SELECT dbo.Percentile (Value, 95) FROM Table

Imports Microsoft.SqlServer.Server
Imports System.Data.SqlTypes
Imports System.IO

<Serializable>
<SqlUserDefinedAggregate(Format.UserDefined, IsInvariantToNulls:=True, IsInvariantToDuplicates:=False, _
  IsInvariantToOrder:=True, MaxByteSize:=-1, IsNullIfEmpty:=True)>
Public Class Percentile
  Implements IBinarySerialize
  Private _items As List(Of Decimal)
  Private _percentile As Integer

  Public Sub Init()
    _items = New List(Of Decimal)()
  End Sub

  Public Sub Accumulate(value As SqlDecimal, percentile As SqlInt32)
    _percentile = percentile
    If Not value.IsNull Then
      _items.Add(value.Value)
    End If
  End Sub

  Public Sub Merge(other As Percentile)
    _percentile = other._percentile
    If other._items IsNot Nothing Then
      _items.AddRange(other._items)
    End If
  End Sub

  Public Function Terminate() As SqlDecimal
    If _items.Count <> 0 Then
      Dim result As Decimal
      _items = _items.OrderBy(Function(i) i).ToList()

      Dim index = Convert.ToInt32(Math.Round((_percentile / 100D) * _items.Count, 0))
      If (index <> 0) Then
        index -= 1
      End If
      result = _items(index)

      Return New SqlDecimal(result)
    Else
      Return New SqlDecimal()
    End If
  End Function

  Public Sub Read(r As BinaryReader) Implements IBinarySerialize.Read
    'deserialize it from a string
    Dim list = r.ReadString()

    If Not (String.IsNullOrEmpty(list)) Then
      Dim index = list.IndexOf("|"c)

      If index <> -1 Then
        _items = New List(Of Decimal)
        _percentile = Convert.ToInt32(list.Substring(0, index))
        list = list.Substring(index + 1)

        For Each value In list.Split(","c)
          Dim number As Decimal
          If Decimal.TryParse(value, number) Then
            _items.Add(number)
          End If
        Next
      End If
    End If
  End Sub

  Public Sub Write(w As BinaryWriter) Implements IBinarySerialize.Write
    'serialize the list to a string
    Dim list As String = ""

    If (_items IsNot Nothing AndAlso _items.Count > 0) Then
      list = Convert.ToString(_percentile) + "|"
      For Each item In _items
        If Not list.EndsWith("|") Then
          list += ","
        End If
        list += item.ToString("#0.0##")
      Next
    End If
    w.Write(list)
  End Sub
End Class

Затем скомпилируйте его, скопируйте файл DLL и PDB на компьютер с SQL Server и выполните следующую команду в SQL Server.:

CREATE ASSEMBLY CustomAggregate FROM '{path to your DLL}'
WITH PERMISSION_SET=SAFE;
GO

CREATE AGGREGATE Percentile(@value decimal(9, 3), @percentile int)
RETURNS decimal(9, 3) 
EXTERNAL NAME [CustomAggregate].[{namespace of your DLL}.Percentile];
GO
0 голосов
/ 18 января 2012

95-й процентиль формулы MAX (RowNumber) * 95/100 * * тысяча один

WITH kali1(k1, k2, k3, k4, k5, k6, k7) AS 
(
    SELECT MinsInAE,
           HoursInAE,
           DaysInAE AS DaysInAE,
           Month_Name,
           YearName,
           InternalNo,
           ROW_NUMBER() OVER(PARTITION BY Month_Name ORDER BY MinsInAE ASC) AS 
           'Row Number'
    FROM   AE.FactAandE
           INNER JOIN AE.PMI
                ON  AE.FactAandE.FK_PaitentMasterIndex = AE.PMI.PK_Patient
           INNER JOIN dbo.TimeDimension
                ON  dbo.TimeDimension.DateId = AE.FactAandE.FK_date
    WHERE  YearName = 'Calendar 2010'
) 
,
kali2(k21, k22, k23)
AS 
(
    SELECT MAX(k7) * 95 / 100,
           k4,
           MAX(k7)
    FROM   kali1
    GROUP BY
           k4
)
SELECT kali2.k21   AS percentilerow,
       kali2.k22   AS Month_Name,
       (kali1.k1)  AS percentilevalue
FROM   kali2
       INNER JOIN kali1
            ON  kali1.k4 = kali2.k22
WHERE  kali1.k7 = kali2.k21
0 голосов
/ 18 января 2012

Я тоже работаю в NHS, вот SQL, который я написал, чтобы узнать медиану, МАКС и 95-й процентиль проверить это и напишите мне kali.tummala@gmail.com

WITH    kali1 ( k1, k2, k3, k4, k5, k6, k7 )
          AS ( SELECT   MinsInAE ,
                        HoursInAE ,
                        DaysInAE AS DaysInAE ,
                        Month_Name ,
                        YearName ,
                        InternalNo ,
                        ROW_NUMBER() OVER ( PARTITION BY Month_Name ORDER BY MinsInAE ASC ) AS 'Row Number'
               FROM     AE.FactAandE
                        INNER JOIN AE.PMI ON AE.FactAandE.FK_PaitentMasterIndex = AE.PMI.PK_Patient
                        INNER JOIN dbo.TimeDimension ON dbo.TimeDimension.DateId = AE.FactAandE.FK_date
               WHERE    YearName = 'Calendar 2010'
             ),
        kali2 ( k21, k22, k23 )
          AS ( SELECT   MAX(k7) * 95 / 100 ,
                        k4 ,
                        MAX(k7)
               FROM     kali1
               GROUP BY k4
             ),
        kali3 ( k31, k32 )
          AS ( SELECT   AVG(1.0E * MinsInAE) AS Median ,
                        Month_Name
               FROM     ( SELECT    MinsInAE ,
                                    Month_Name ,
                                    2
                                    * ROW_NUMBER() OVER ( PARTITION BY Month_Name ORDER BY MinsInAE )
                                    - COUNT(*) OVER ( PARTITION BY Month_Name ) AS y
                          FROM      AE.FactAandE
                                    INNER JOIN AE.PMI ON AE.FactAandE.FK_PaitentMasterIndex = AE.PMI.PK_Patient
                                    INNER JOIN dbo.TimeDimension ON dbo.TimeDimension.DateId = AE.FactAandE.FK_date
                          WHERE     YearName = 'Calendar 2010'
                        ) AS d
               WHERE    y BETWEEN 0 AND 2
               GROUP BY Month_Name
             ),
        kali4 ( k41, k42, k43, k44, k46, k47 )
          AS ( SELECT   MinsInAE ,
                        HoursInAE ,
                        DaysInAE AS DaysInAE ,
                        Month_Name ,
                        YearName ,
                        InternalNo
               FROM     AE.FactAandE
                        INNER JOIN AE.PMI ON AE.FactAandE.FK_PaitentMasterIndex = AE.PMI.PK_Patient
                        INNER JOIN dbo.TimeDimension ON dbo.TimeDimension.DateId = AE.FactAandE.FK_date
               WHERE    YearName = 'Calendar 2010'
             ),
        kali5 ( k51, k52, k53 )
          AS ( SELECT   kali2.k22 AS Month_Name ,
                        ( kali1.k1 ) AS percentilevalue ,
                        kali2.k21 AS percentilerow
               FROM     kali2
                        INNER JOIN kali1 ON kali1.k4 = kali2.k22
               WHERE    kali1.k7 = kali2.k21
             )
    SELECT  kali3.k31 AS Median ,
            kali3.k32 AS Month_Name ,
            MAX(kali4.k41) AS Max_Mins_In_AE ,
            SUM(kali4.k41) AS Mins_IN_AE ,
            kali5.k51 AS Month_Name ,
            kali5.k52 AS percentile
    FROM    kali3
            LEFT JOIN kali4 ON kali3.k32 = kali4.k44
            LEFT JOIN kali5 ON kali5.k51 = kali3.k32
    GROUP BY kali3.k31 ,
            kali3.k32 ,
            kali5.k51 ,
            kali5.k52
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...