Sqlserver
 sql >> база данни >  >> RDS >> Sqlserver

Избиране на поднабор от редове, които надвишават процент от общите стойности

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; 

LiveDemo2

Изход:

<предварителен код>╔══════════╦═══════╦═════════╦════════════ ══╦════════════════════╗║ Клиент ║ Потребител ║ Приходи ║ Процент ║ 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;  

LiveDemo3

Изход:

<предварителен код>╔══════════╦═══════╦═════════╦════════════ ══╦════════════════════╗║ Клиент ║ Потребител ║ Приходи ║ Процент ║ 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; 

LiveDemo4



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. OrderBy в SQL Server за поставяне на положителни стойности преди отрицателни стойности

  2. Какви са еквивалентните C# типове данни за дата, час и отместване на дата и време на SQL Server?

  3. Как да възстановите база данни на SQL Server чрез C# код

  4. Driver.getConnection виси с помощта на драйвер на SQLServer и Java 1.6.0_29

  5. Редове на SQL Server не могат да се редактират за Access след вмъкване