我正在尝试编写一个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,100 202,2,80 303、1、60 404,1,40 505、1、20
我想这个解决方案可能涉及到ROW_NUMBER
,我从这条路径开始,以为我可以得到ROW_NUMBER /总计行* 100,但由于某些原因,这是行不通的。可能是因为集团的条款?
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
如果可能的话,我更愿意在单个选择中这样做,但如果不将其包装在外部选择中,则可能是一个解决方案。谢谢
发布于 2017-03-30 05:09:46
COUNT函数和ROW_NUMBER函数都返回BIGINT。因此,除法的结果也转化为BIGINT。
这是可行的(你应该在除以前乘以):
(ROW_NUMBER() OVER(order by (count(*)))) * 100 / (count(*) over ()) as Percentage
发布于 2017-03-30 05:15:53
使用类似于您的问题的count() over()
和row_number()
,只需重新排序方程。
请注意,用于order by
的row_number()
与语句的order by
相反,因为我们希望将百分比从100开始。否则,您可以以80作为第一行,100作为第二行,等等。
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
rextester演示:http://rextester.com/TCPE10348
+---------+--------------+------------+
| StockId | BinMovements | Percentage |
+---------+--------------+------------+
| 101 | 2 | 100 |
| 202 | 2 | 80 |
| 303 | 1 | 60 |
| 404 | 1 | 40 |
| 505 | 1 | 20 |
+---------+--------------+------------+
如果您想要小数百分比,请将方程中的100
更改为100.0
。
https://stackoverflow.com/questions/43118673
复制