Мне не очень нравится, когда глубина рекурсии зависит от количества строк в данных, а не от фактической глубины данных.Это решение работает хорошо для меня, потому что у меня так мало строк для ранжирования.Тем не менее, для будущих читателей, если у кого-то есть нерекурсивное решение, я с радостью отмечу его как ответ, а не как мое.
Чтобы продемонстрировать этот набор на основе IS, я добавил GROUP BYколонка.Глубина рекурсии зависит от количества элементов для оценки, а не от количества групп.Все группы обрабатываются одновременно.Этот код был протестирован на моем наборе производственных данных и сравнен с ответами, генерируемыми последовательным циклом по данным, поэтому я знаю, что он работает с большими и более сложными наборами данных.
WITH T AS (
SELECT *
FROM(VALUES ('Type1', 65550 ,2109 ,1),('Type2', 65550 ,2109 ,1),
('Type1', 67188 ,2050 ,1),('Type2', 67188 ,2050 ,1),
('Type1', 67407 ,2146 ,1),('Type2', 67407 ,2146 ,1),
('Type1', 67414 ,1973 ,1),('Type2', 67414 ,1973 ,1),
('Type1', 67486 ,1889 ,2),('Type2', 67486 ,1889 ,2),
('Type1', 67581 ,2320 ,2),('Type2', 67581 ,2320 ,2),
('Type1', 67858 ,1993 ,2),('Type2', 67858 ,1993 ,2),
('Type1', 68509 ,2029 ,2),('Type2', 68509 ,2029 ,2),
('Type1', 68645 ,2039 ,2),('Type2', 68645 ,2039 ,2),
('Type1', 68868 ,2051 ,2),('Type2', 68868 ,2051 ,2),
('Type1', 68902 ,1943 ,2),('Type2', 68902 ,1943 ,2),
('Type1', 69305 ,1564 ,3),('Type2', 69305 ,1564 ,3),
('Type1', 69430 ,2037 ,3),('Type2', 69430 ,2037 ,3),
('Type1', 69509 ,1594 ,3),('Type2', 69509 ,1594 ,3)) X(TestType,AvgScore,StdErr,DesiredRank)
), X AS (
SELECT *,ROW_NUMBER() OVER(PARTITION BY TestType ORDER BY AvgScore) GRow,1 Rnk,AvgScore RAvg, AvgScore+StdErr RMax
FROM T
), Y AS (
SELECT TestType,AvgScore,StdErr,DesiredRank,GRow,Rnk,RAvg,RMax,0 NewRank,0 pravg,0 prmin
FROM X
WHERE GRow = 1
UNION ALL
SELECT Z.TestType,Z.AvgScore,Z.StdErr,Z.DesiredRank,Z.GRow
,CASE WHEN W.NewRank = 1 THEN Y.Rnk+1 ELSE Y.Rnk END Rnk
,CASE WHEN W.NewRank = 1 THEN Z.RAvg ELSE Y.RAvg END RAvg
,CASE WHEN W.NewRank = 1 THEN Z.RMax ELSE Y.RMax END RMin
,W.NewRank,Y.RAvg pravg,y.RMax prmin
FROM Y
CROSS APPLY (SELECT * FROM X WHERE X.TestType=Y.TestType and X.GRow = Y.GRow+1) Z
CROSS APPLY (VALUES (CASE WHEN Z.AvgScore <= Y.RMax and Z.AvgScore - Z.StdErr <= Y.RAvg THEN 0 ELSE 1 END)) W(NewRank)
)
SELECT * FROM Y
ORDER BY TestType,AvgScore;