2011-07-05 2 views
0

SQLサーバー2008の機能で95パーセンタイルとメジアンビルドを調べようとしましたが、なぜMSがそれらをサポートしないのか分かりません。私たちの仕事場レポートは非​​常に複雑で、ストレートフォワード関数を望んでいたか、通常の関数として使用するためにSQLサーバと組み立てることができるdllファイルかもしれません。SQL Server 2008の中央値と95パーセンタイル? - NHSの報告書の要求

いずれかのアドバイスがあります。前もって感謝します。

Reagrds アリ

答えて

1

NTILE機能がありますし、中央値はthisをお読みください。私はここにもNHSのために働く

+0

乾杯!Mladen Prajdic!私はこの関数と記事を調べる予定ですが、もし何かが動的リンクを見つけるのを助けることができるなら、libraby(dll)をSQLサーバーと組み立てて、これらの機能をビルドに組み込むことは非常に役に立ちます。お返事ありがとうございました –

-1

が、このうち、私に[email protected]

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 
0

95番目に電子メールを送り、私は中央値、MAXを見つけるために書いたwhcih SQL、および95パーセンタイル チェックですパーセンタイル式は MAX(ROWNUMBER)* 100分の95

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 
+1

このSQLコードをフォーマットしてください。 –

0

あなたは、SQL Serverで使用するカスタム集計関数を作成することにより、これを行うには、Visual StudioでDLLを作成することができます。これを行うには、新しいVisual Studioプロジェクトを作成し、ターゲットフレームワークを.NET 3.5に設定します(これはSQL 2008の場合、SQL 2012では異なる場合があります)。次に、クラスファイルを作成し、次のコードまたは同等のC#を入力します。

このアルゴリズムは、指定された百分位数に最も近い値を取得することに注意してください。別の百分位数アルゴリズムを使用する場合は、そのコードを変更することができます。

このプロセスによって、ユーザーは照会するパーセンタイルを入力できます。クエリは次のようになります。

テーブルからdbo.Percentile(バリュー、95)を選択
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 

そして、それをコンパイルして、SQL ServerマシンにDLLとPDBファイルをコピーして、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