NTILE() によって提供されるものと同様の T-SQL ランキング アプローチが必要です。ただし、各タイルのメンバーがスライド分布になるため、ランキングの高いタイルほどメンバーが少なくなります。
例えば
CREATE TABLE #Rank_Table(
id int identity(1,1) not null,
hits bigint not null default 0,
PERCENTILE smallint null
)
--Slant the distribution of the data
INSERT INTO #Rank_Table (hits)
select CASE
when DATA > 9500 THEN DATA*30
WHEN data > 8000 THEN DATA*5
WHEN data < 7000 THEN DATA/3 +1
ELSE DATA
END
FROM
(select top 10000 (ABS(CHECKSUM(NewId())) % 99 +1) * (ABS(CHECKSUM(NewId())) % 99 +1 ) DATA
from master..spt_values t1
cross JOIN master..spt_values t2) exponential
Declare @hitsPerGroup as bigint
Declare @numGroups as smallint
set @numGroups=100
select @hitsPerGroup=SUM(hits)/(@numGroups -1) FROM #Rank_Table
select @hitsPerGroup HITS_PER_GROUP
--This is an even distribution
SELECT id,HITS, NTILE(@numGroups) Over (Order By HITS DESC) PERCENTILE
FROM #Rank_Table
GROUP by id, HITS
--This is my best attempt, but it skips groups because of the erratic distribution
select
T1.ID,
T1.hits,
T.RunningTotal/@hitsPerGroup + 1 TILE,
T.RunningTotal
FROM #Rank_Table T1
CROSS APPLY ( Select SUM(hits) RunningTotal FROM #Rank_Table where hits <= T1.hits) T
order by T1.hits
DROP TABLE #Rank_Table
#Rank_table では、NTILE(@numGroups) は @numGroups グループの均等な分散を作成します。必要なのは、タイル 1 のメンバーが最も少なく、タイル 2 がタイル 1 よりも 1 つ以上、タイル 3 がタイル 2 よりも 1 つ以上のメンバーを持つ @numGroups グループです。タイル 100 が最も多くなります。
SQL Server 2008 を使用しています。実際には、PERCENTILE 列を 1 ~ 100 のパーセンタイルで定期的に更新するために、数百万行になる可能性がある永続テーブルに対して実行されます。
上記の私の最善の試みは、パーセンタイルをスキップし、パフォーマンスが低下します。もっと良い方法があるはずです。