it-swarm-tr.com

MS SQL'de yüzdelik sıralamayı hesaplama

MSSQL 2005’teki yüzdelik sıralamayı (ör. 90. yüzde ya da ortanca puan) hesaplamanın en iyi yolu nedir?

Tek bir puan sütunu için 25'inci, ortanca ve 75'inci yüzdeleri seçebilmeyi isterim (tercihen tek bir kayıtta, ortalama, maksimum ve min ile birleştirebilirim). Örneğin, sonuçların tablo çıktısı şöyle olabilir:

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

Bunun en basit çözüm olacağını düşünürdüm:

SELECT TOP N PERCENT FROM TheTable ORDER BY TheScore DESC

N = (100 - istenen yüzdelik). Bu yüzden, yüzde 90’daki tüm satırları istiyorsanız, ilk% 10’u seçersiniz.

"Tercihen tek bir kayıtta" derken ne demek istediğinizi anlamadım. Tek bir kayıt için verilen puanın yüzde kaçının düşeceğini hesaplamak mı demek istiyorsun? Örneğin. "puanınız 83, sizi yüzde 91’e sokan" gibi ifadeler yapabilmek ister misiniz? ?

EDIT: Tamam, sorunuz hakkında biraz daha düşündüm ve bu yorumu geldi. Belirli bir yüzdelik kesim için kesme puanının nasıl hesaplanacağını mı soruyorsunuz? Örneğin. Bunun gibi bir şey: 90'ıncı yüzde oranına girebilmek için 78'den büyük bir puana sahip olmalısın.

Eğer öyleyse, bu sorgu çalışır. Yine de alt sorguları sevmediğim için ne için olduğuna bağlı olarak, muhtemelen daha zarif bir çözüm bulmaya çalışırım. Bununla birlikte, tek bir skorla tek bir kayıt döndürür.

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

NTILE komutunu kontrol edin - size oldukça kolay yüzdelik kazandıracak!

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

Buna ne dersin:

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'nci yüzdelik, medyan ile aynıdır. Diğer yüzdelik değerleri hesaplarken 80. diyelim, verinin yüzde 80'ini artan sırada ve yüzde 20'sini azalan sırada sıralayın ve iki orta değerin ortalamasını alın.

Not: Medyan sorgusu uzun zamandır etraftaydı, ancak tam olarak nereden aldığımı hatırlayamıyorum, sadece diğer yüzdelikleri hesaplamak için değiştirdim.

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

Bu konuda biraz daha çalıştım ve işte şimdiye kadar bulduğum şey:

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

Sonra başka bir saklı yordamda bunu yapıyorum:

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

Hala aradığım şeyi yapmıyor. Bu, tüm testlerin istatistiklerini alacak; bununla birlikte, içinde birden fazla farklı test içeren bir TestScores tablosundan seçim yapabilmek ve her farklı test için aynı istatistikleri geri alabilmeyi istiyorum (benim sorumla ilgili örnek tablomda olduğu gibi).

1
Soldarnal

Yüzde

(Rank -1) /(total_rows -1), değerleri artan düzende sıraladığınızda.

Aşağıdaki sorgu, 0 ile 1 arasında size yüzde değeri verir.

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

muhtemelen bir sql server 2005 kullanırdım 

row_number () üstü (skora göre sırala)/(puanlardan sayı seç (*))

veya bu çizgiler boyunca bir şey. 

0
karl prosser

şöyle bir şey yapardım:

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

bu doğru mu?

0
syap