26

MSSQL 2005 でパーセンタイル ランキング (90 パーセンタイルまたは中央値スコアなど) を計算する最良の方法は何ですか?

スコアの 1 つの列に対して 25、中央値、および 75 パーセンタイルを選択できるようにしたいと考えています (平均、最大、および最小と組み合わせることができるように、単一のレコードであることが望ましいです)。たとえば、結果のテーブル出力は次のようになります。

Group  MinScore  MaxScore  AvgScore  pct25  median  pct75
-----  --------  --------  --------  -----  ------  -----
T1     52        96        74        68     76      84
T2     48        98        74        68     75      85
4

8 に答える 8

15

これが最も簡単な解決策になると思います。

SELECT TOP N PERCENT FROM TheTable ORDER BY TheScore DESC

ここで、N =(100-目的のパーセンタイル)。したがって、90パーセンタイルのすべての行が必要な場合は、上位10%を選択します。

「できれば単一のレコードで」とはどういう意味かわかりません。単一のレコードの特定のスコアがどのパーセンタイルに該当するかを計算することを意味しますか?たとえば、「スコアは83で、91パーセンタイルになります」などのステートメントを作成できるようにしますか。?

編集:わかりました、私はあなたの質問についてもう少し考えて、この解釈を思いつきました。特定のパーセンタイルのカットオフスコアを計算する方法を尋ねていますか?たとえば、次のようなものです。90パーセンタイルに入るには、78を超えるスコアが必要です。

その場合、このクエリは機能します。サブクエリは嫌いなので、目的によっては、もっとエレガントな解決策を見つけようと思うでしょう。ただし、単一のスコアを持つ単一のレコードを返します。

-- Find the minimum score for all scores in the 90th percentile
SELECT Min(subq.TheScore) FROM
(SELECT TOP 10 PERCENT TheScore FROM TheTable
ORDER BY TheScore DESC) AS subq
于 2008-09-17T04:28:03.003 に答える
9

NTILE コマンドを確認してください。パーセンタイルを簡単に取得できます。

SELECT  SalesOrderID, 
    OrderQty,
    RowNum = Row_Number() OVER(Order By OrderQty),
    Rnk = RANK() OVER(ORDER BY OrderQty),
    DenseRnk = DENSE_RANK() OVER(ORDER BY OrderQty),
    NTile4  = NTILE(4) OVER(ORDER BY OrderQty)
FROM Sales.SalesOrderDetail 
WHERE SalesOrderID IN (43689, 63181)
于 2011-06-28T20:42:40.940 に答える
2

これはどう:

SELECT
  Group,
  75_percentile =  MAX(case when NTILE(4) OVER(ORDER BY score ASC) = 3 then score  else 0 end),
  90_percentile =  MAX(case when NTILE(10) OVER(ORDER BY score  ASC) = 9 then score  else 0 end)     
FROM TheScore
GROUP BY Group
于 2012-09-05T23:24:14.127 に答える
1

50パーセンタイルは中央値と同じです。他のパーセンタイル、たとえば80を計算するときは、データの80%を昇順で並べ替え、残りの20%を降順で並べ替えて、2つの中間値の平均を取ります。

注意:中央値クエリは長い間存在していましたが、正確にどこから取得したかを思い出せません。他のパーセンタイルを計算するために修正しただけです。

DECLARE @Temp TABLE(Id INT IDENTITY(1,1), DATA DECIMAL(10,5))

INSERT INTO @Temp VALUES(0)
INSERT INTO @Temp VALUES(2)
INSERT INTO @Temp VALUES(8)
INSERT INTO @Temp VALUES(4)
INSERT INTO @Temp VALUES(3)
INSERT INTO @Temp VALUES(6)
INSERT INTO @Temp VALUES(6)
INSERT INTO @Temp VALUES(6) 
INSERT INTO @Temp VALUES(7)
INSERT INTO @Temp VALUES(0)
INSERT INTO @Temp VALUES(1)
INSERT INTO @Temp VALUES(NULL)


--50th percentile or median
SELECT ((
        SELECT TOP 1 DATA
        FROM   (
                SELECT  TOP 50 PERCENT DATA
                FROM    @Temp
                WHERE   DATA IS NOT NULL
                ORDER BY DATA
                ) AS A
        ORDER BY DATA DESC) + 
        (
        SELECT TOP 1 DATA
        FROM   (
                SELECT  TOP 50 PERCENT DATA
                FROM    @Temp
                WHERE   DATA IS NOT NULL
                ORDER BY DATA DESC
                ) AS A
        ORDER BY DATA ASC)) / 2.0


--90th percentile 
SELECT ((
        SELECT TOP 1 DATA
        FROM   (
                SELECT  TOP 90 PERCENT DATA
                FROM    @Temp
                WHERE   DATA IS NOT NULL
                ORDER BY DATA
                ) AS A
        ORDER BY DATA DESC) + 
        (
        SELECT TOP 1 DATA
        FROM   (
                SELECT  TOP 10 PERCENT DATA
                FROM    @Temp
                WHERE   DATA IS NOT NULL
                ORDER BY DATA DESC
                ) AS A
        ORDER BY DATA ASC)) / 2.0


--75th percentile
SELECT ((
        SELECT TOP 1 DATA
        FROM   (
                SELECT  TOP 75 PERCENT DATA
                FROM    @Temp
                WHERE   DATA IS NOT NULL
                ORDER BY DATA
                ) AS A
        ORDER BY DATA DESC) + 
        (
        SELECT TOP 1 DATA
        FROM   (
                SELECT  TOP 25 PERCENT DATA
                FROM    @Temp
                WHERE   DATA IS NOT NULL
                ORDER BY DATA DESC
                ) AS A
        ORDER BY DATA ASC)) / 2.0
于 2011-06-28T10:21:41.173 に答える
1

私はこれにもう少し取り組んできました、そしてこれが私がこれまでに思いついたものです:

CREATE PROCEDURE [dbo].[TestGetPercentile]

@percentile as float,
@resultval as float output

AS

BEGIN

WITH scores(score, prev_rank, curr_rank, next_rank) AS (
    SELECT dblScore,
        (ROW_NUMBER() OVER ( ORDER BY dblScore ) - 1.0) / ((SELECT COUNT(*) FROM TestScores) + 1)  [prev_rank],
        (ROW_NUMBER() OVER ( ORDER BY dblScore ) + 0.0) / ((SELECT COUNT(*) FROM TestScores) + 1)  [curr_rank],
        (ROW_NUMBER() OVER ( ORDER BY dblScore ) + 1.0) / ((SELECT COUNT(*) FROM TestScores) + 1)  [next_rank]
    FROM TestScores
)

SELECT @resultval = (
    SELECT TOP 1 
    CASE WHEN t1.score = t2.score
        THEN t1.score
    ELSE
        t1.score + (t2.score - t1.score) * ((@percentile - t1.curr_rank) / (t2.curr_rank - t1.curr_rank))
    END
    FROM scores t1, scores t2
    WHERE (t1.curr_rank = @percentile OR (t1.curr_rank < @percentile AND t1.next_rank > @percentile))
        AND (t2.curr_rank = @percentile OR (t2.curr_rank > @percentile AND t2.prev_rank < @percentile))
)

END

次に、別のストアドプロシージャでこれを行います。

DECLARE @pct25 float;
DECLARE @pct50 float;
DECLARE @pct75 float;

exec SurveyGetPercentile .25, @pct25 output
exec SurveyGetPercentile .50, @pct50 output
exec SurveyGetPercentile .75, @pct75 output

Select
    min(dblScore) as minScore,
    max(dblScore) as maxScore,
    avg(dblScore) as avgScore,
    @pct25 as percentile25,
    @pct50 as percentile50,
    @pct75 as percentile75
From TestScores

それでも私が探していることはまったくできません。これにより、すべてのテストの統計が取得されます。一方、複数の異なるテストが含まれているTestScoresテーブルから選択して、異なるテストごとに同じ統計を取得できるようにしたいと思います(質問の例のテーブルにあるように)。

于 2008-12-05T00:13:13.427 に答える
0

私は次のようなことをします:

select @n = count(*) from tbl1
select @median = @n / 2
select @p75 = @n * 3 / 4
select @p90 = @n * 9 / 10

select top 1 score from (select top @median score from tbl1 order by score asc) order by score desc

これは正しいですか?

于 2008-09-17T03:48:22.443 に答える
0

私はおそらくSQL Server 2005を使用します

row_number() over (スコア順) / (スコアから count(*) を選択)

またはそれらの線に沿った何か。

于 2008-09-17T03:47:33.350 に答える
0

パーセンタイルは次のように計算されます

(Rank -1) /(total_rows -1)値を昇順で並べ替えるとき。

以下のクエリは、0 から 1 の間のパーセンタイル値を提供します。最も低い点数の人は 0 パーセンタイルになります。

SELECT Name, marks, (rank_1-1)/((select count(*) as total_1 from table)-1)as percentile_rank
from
(
SELECT Name,
       Marks,
       RANK() OVER (ORDER BY Marks) AS rank_1
       from table
) as A
于 2019-03-08T15:37:01.800 に答える