根据sql中的row_number计算百分比

时间:2017-03-30 13:01:24

标签: sql-server group-by

我正在尝试编写一个sql查询,对于每个返回的行,也会根据其行位置返回一个百分比(0-100)。为了进一步复杂化,查询目前也已分组。以下是一些可以使用的示例数据:

create table #test(StockId int)
insert into #test values (101), (101), (202), (202), (303), (404), (505)

select 
StockId,
count(*) as BinMovements
from #test
group by StockId
order by BinMovements desc

此查询当前返回:

  

StockId,BinMovements
  101,2   202,2   303,1   404,1   505,1

(虽然很明显,因为BinMovements是2或1,所以以不同的顺序返回StockIds同样正确):

  

202,2
  101,2   404,1   303,1   505,1

我想添加一个'百分比'列,但这实际上只是基于行位置,所以我希望看到以下值:

  

101,2,11
  202,2,80   303,1,61   404,1,40   505,1,20

我想解决方案可能涉及ROW_NUMBER,我开始沿着这条路走下去,以为我可以得到ROW_NUMBER /总行数* 100,但由于某些原因这不起作用。可能是因为group by子句?

select 
StockId,
count(*) as BinMovements,
ROW_NUMBER() OVER(order by (count(*))) as RowNumber,
count(*) over () as TotalCount,
(ROW_NUMBER() OVER(order by (count(*)))) / (count(*) over ()) * 100 as Percentage
from #test
group by StockId
order by RowNumber desc

返回:

StockId BinMovements    RowNumber   TotalCount  Percentage
202     2               5           5           100
101     2               4           5           0
505     1               3           5           0
404     1               2           5           0
303     1               1           5           0

如果可能的话,我宁愿在单个选择中执行此操作,但如果不将其包装在外部选择中可能是一种解决方案。感谢

2 个答案:

答案 0 :(得分:1)

COUNT和ROW_NUMBER函数都返回BIGINT。 因此除法的结果也转换为BIGINT。

这有效(你应该在分裂之前相乘):

(ROW_NUMBER() OVER(order by (count(*)))) * 100 / (count(*) over ()) as Percentage

答案 1 :(得分:1)

使用类似于您问题的count() over()row_number(),只需重新排序等式。

请注意,order by的{​​{1}}与语句的row_number()相反,因为我们希望将百分比设置为100.否则您最终可以将80作为第一行,100作为第二行,等等。

order by

rextester演示:http://rextester.com/TCPE10348

select 
    StockId
  , BinMovements = count(*)
  , Percentage = 100/count(*) over () 
    * row_number() over (order by count(*) asc, stockid desc)
from #test
group by StockId
order by BinMovements desc, StockId asc

如果您想要小数百分比,请在等式中将+---------+--------------+------------+ | StockId | BinMovements | Percentage | +---------+--------------+------------+ | 101 | 2 | 100 | | 202 | 2 | 80 | | 303 | 1 | 60 | | 404 | 1 | 40 | | 505 | 1 | 20 | +---------+--------------+------------+ 更改为100