我需要一种类似于 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 组的均匀分布。我需要的是@numGroups 组,其中磁贴 1 的成员最少,磁贴 2 将有一个或多个磁贴 1,磁贴 3 将有 1 个或多于磁贴 2 ...磁贴 100 将具有最多。
我正在使用 SQL Server 2008。实际上,这将针对可能具有数百万行的永久表运行,以便定期更新 PERCENTILE 列,其百分位数为 1-100。
我上面的最佳尝试将跳过百分位数并且表现不佳。一定会有更好的办法。