it-swarm-ko.tech

MS SQL에서 백분위 수 순위 계산

MSSQL 2005에서 백분위 수 순위 (예 : 90 번째 백분위 수 또는 중간 점수)를 계산하는 가장 좋은 방법은 무엇입니까?

단일 열의 열에 대해 25 번째, 중간 값 및 75 번째 백분위 수를 선택할 수 있기를 원합니다 (단일 레코드에서 평균, 최대 및 최소와 결합 할 수 있음). 예를 들어 결과의 테이블 출력은 다음과 같습니다.

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

이것이 가장 간단한 해결책이라고 생각합니다.

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
15
Matt

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)
9
Elizabeth

이건 어때요:

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
2
Paul

50 번째 백분위 수는 중앙값과 같습니다. 80 번째와 같은 다른 백분위 수를 계산할 때는 데이터의 80 %에 대한 데이터를 오름차순으로 정렬하고 나머지 20 %를 내림차순으로 정렬하고 두 중간 값의 평균을 취합니다.

NB : 중간 쿼리는 오랫동안 사용되어 왔지만 정확히 어디서 왔는지 기억할 수 없으며 다른 백분위 수를 계산하기 위해 수정했습니다.

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
1
Kay Aliu

나는 이것을 조금 더 연구 해 왔으며, 지금까지 내가 생각해 낸 것은 다음과 같습니다.

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 테이블에서 선택하고 각 테스트마다 동일한 통계를 반환하고 싶습니다 (내 질문의 예제 테이블에있는 것처럼).

1
Soldarnal

백분위 수는

(Rank -1) /(total_rows -1) 오름차순으로 값을 정렬 할 때.

아래 쿼리는 0과 1 사이의 백분위 수 값을 제공합니다. 가장 낮은 점수를받은 사람은 백분위 수를 갖습니다.

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
0
Debasmita

아마도 SQL Server 2005를 사용했을 것입니다.

row_number () 초과 (점수 순)/(점수에서 카운트 (*) 선택)

또는 그 라인을 따라 뭔가.

0
karl prosser

나는 다음과 같은 것을 할 것이다 :

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

이게 옳은 거니?

0
syap