SQL Server 2012+
само
Можете да използвате прозорец SUM
:
WITH cte AS( SELECT *, 1.0 * Revenue/SUM(Revenue) OVER(PARTITION BY [User]) AS процентил, 1.0 * SUM(Revenue) OVER(PARTITION BY [User] ORDER BY [Revenue] DESC) /SUM(Revenue) OVER(PARTITION BY [User]) AS running_percentile FROM tab)SELECT *FROM cte WHERE running_percentile <=0,8;
SQL Server 2008:
WITH cte AS( SELECT *, ROW_NUMBER() OVER(PARTITION BY [User] ORDER BY Revenue DESC) AS rn FROM t), cte2 AS( SELECT c.Customer, c.[User], c. [Приходи] ,процентил =1.0 * Приходи / NULLIF(c3.s,0) ,текущ_процентил =1.0 * c2.s / NULLIF(c3.s,0) ОТ cte c КРЪСТОСНО ПРИЛАГАНЕ (ИЗБЕРЕТЕ СУМА(Приходи) КАТО s ОТ cte c2 WHERE c.[Потребител] =c2.[Потребител] И c2.rn <=c.rn) c2 КРЪСТОСНО ПРИЛАГАНЕ (ИЗБЕРЕТЕ СУМА(Приход) AS s FROM cte c2 WHERE c.[Потребител] =c2.[Потребител]) AS c3) SELECT *FROM cte2WHERE run_percentile <=0,8;
Изход:
<предварителен код>╔══════════╦═══════╦═════════╦════════════ ══╦════════════════════╗║ Клиент ║ Потребител ║ Приходи ║ Процент ║ Running_Percentile ║╠══════════╬═══ ════╬═════════╬════════════════╬══════════════════ ══╣║ 2 ║ James ║ 750 ║ 0,384615384615 ║ 0,384615384615 ║║ 1 ║ James ║ 500 ║ 0,256410256410 ║ 0,641025641025 ║║ 7 ║ Sarah ║ 600 ║ 0,444444444444 ║ 0,444444444444 ║╚═ ═════════╩═══════╩═════════╩════════════════╩═════ ═══════════════╝РЕДАКТИРАНЕ 2:
WITH cte AS( SELECT *, ROW_NUMBER() OVER(PARTITION BY [User] ORDER BY Revenue DESC) AS rn FROM t), cte2 AS( SELECT c.Customer, c.[User], c. [Приходи] ,процентил =1.0 * Приходи / NULLIF(c3.s,0) ,текущ_процентил =1.0 * c2.s / NULLIF(c3.s,0) ОТ cte c КРЪСТОСНО ПРИЛАГАНЕ (ИЗБЕРЕТЕ СУМА(Приходи) КАТО s ОТ cte c2 WHERE c.[Потребител] =c2.[Потребител] И c2.rn <=c.rn) c2 КРЪСТОСНО ПРИЛАГАНЕ (ИЗБЕРЕТЕ СУМА(Приход) AS s FROM cte c2 WHERE c.[Потребител] =c2.[Потребител]) AS c3) SELECT a.*FROM cte2 aCROSS APPLY (SELECT MIN(running_percentile) AS rp FROM cte2 WHERE running_percentile>=0.8 AND cte2.[User] =a.[User]) AS sWHERE a.running_percentile <=s.rp;
Изход:
<предварителен код>╔══════════╦═══════╦═════════╦════════════ ══╦════════════════════╗║ Клиент ║ Потребител ║ Приходи ║ Процент ║ Running_Percentile ║╠══════════╬═══ ════╬═════════╬════════════════╬══════════════════ ══╣║ 2 ║ James ║ 750 ║ 0,384615384615 ║ 0,384615384615 ║║ 1 ║ James ║ 500 ║ 0,256410256410 ║ 0,641025641025 ║║ 3 ║ James ║ 450 ║ 0,230769230769 ║ 0,871794871794 ║║ 7 ║ Сара ║ 600 ║ 0,444444444444 ║ 0,44444444444 ║║ 5 ║ Sarah ║ 500 ║ 0,370370370370 ║ 0,814814814814 ║╚══════════╩═══════╩══ ═══════╩════════════════╩══════════════════ код>═════
SQL Server 2008
не поддържа всичко в OVER()
клауза, но ROW_NUMBER
прави.
Първо cte просто изчислете позицията в група:
╔═══════════╦════════╦══════════╦════║║ Приходи Клиент ║ ║ rn ║╠═══════════╬════════╬══════════╬════╣║ 2 ║ Джеймс ║ 750 ║ 1 ║ ║ 1 ║ Джеймс ║ 500 ║ 2 ║║ 3 ║ James ║ 450 ║ 3 ║║ 8 ║ James ║ 150 ║ 4 ║║ 9 ║ James ║ 100 ║ 5 ║║ 7 ║ Sarah ║ 600 ║ 1 ║║ 5 ║ Сара ║ 500 ║ 2 ║║ 6 ║ Сара ║ 150 ║ 3 ║║ 4 ║ Сара ║ 100 ║ 4 ║╚═══════════╩════════╩══════ ════╩════╝
Втори cte:
c2
подзаявка изчислява текуща обща сума въз основа на ранг отROW_NUMBER
c3
изчисляване на пълната сума за потребител
В крайната заявка s
подзаявка намира най-ниския работещ
общо, което надхвърля 80%.
РЕДАКТИРАНЕ 3:
Използване на ROW_NUMBER
всъщност е излишен.
WITH cte AS( SELECT c.Customer, c.[User], c.[Revenue] ,percentile =1.0 * Revenue / NULLIF(c3.s,0) ,running_percentile =1.0 * c2.s / NULLIF(c3.s,0) FROM t c CROSS APPLY (SELECT SUM(Revenue) AS s FROM t c2 WHERE c.[User] =c2.[User] AND c2.Revenue>=c.Revenue) c2 CROSS APPLY (SELECT) SUM(Приходи) AS s FROM t c2 WHERE c.[Потребител] =c2.[Потребител]) AS c3) SELECT a.*FROM cte aCROSS APPLY (SELECT MIN(running_percentile) AS rp FROM cte c2 WHERE running_percentile>=0,8 И c2.[Потребител] =a.[Потребител]) AS SWHERE a.running_percentile <=s.rpORDER BY [Потребител], приходи DESC;