2017-03-08 141 views
2

请考虑此表:获取间隔百分比

FileName   FileSize 
---------------------------- 
1     33 
2     198 
3     10 
4     127 
5     85 
6     23 
7     105 
8     158 
9     78 
10     90 

,我想创造这样这样的结果:

FileSize    Percentage 
-------------------------------- 
1-50     30% 
50-150     50% 
150-200     20% 

我怎么能group by并创建一个基于百分比区间?

感谢

回答

2

对于无边界表,你可以创建一个使用值的表内联构造像下面

select DISTINCT 
CAST(I.LowNumber as VARCHAR) + ' - '+ CAST(I.HighNumber as VARCHAR) as FileSize, 
COUNT(*) OVER (PARTITION BY lowNumber,HighNumber ORDER By lowNumber) * 100.00 /COUNT(*) OVER (ORDER BY (SELECT 1)) as percentage 
from TblFile F 
join (values (1, 50),(50, 150),(150, 200)) as I(LowNumber, highNumber) 
on F.FileSize >=I.LowNumber and F.FileSize<I.HighNumber 
Order By I.LowNumber 

您的查询应该像

select DISTINCT 
CAST(I.LowNumber as VARCHAR) + ' - '+ CAST(I.HighNumber as VARCHAR) as FileSize, 
COUNT(*) OVER (PARTITION BY lowNumber,HighNumber ORDER By lowNumber) * 100.00 /COUNT(*) OVER (ORDER BY (SELECT 1)) as percentage 
from TblFile F 
join TblInterval I 
on F.FileSize >=I.LowNumber and F.FileSize<I.HighNumber 

说明查询:

理想情况下,您应该利用基于集合的方法并将范围值存储在表中。这样可以实现更快的处理,并且可以让您在一个地方限制外部而不是在程序中。这也符合依赖注入原则。

对于内联匿名表使用VALUES构造函数。更多关于这在this msdn link

Output image reference:

PS:插入脚本表

--create table tblInterval (LowNumber Int, HighNumber Int) 
--insert into tblInterval values 
--(1,50),(50,150),(150,200) 

create table tblFile (fileName int,fileSize int) 
insert into tblFile values 
(1 ,33) 
,(2 ,198) 
,(3 ,10 ) 
,(4 ,127) 
,(5 ,85 ) 
,(6 ,23 ) 
,(7 ,105) 
,(8 ,158) 
,(9 ,78 ) 
,(10,90 ) 

假设你有一个表像下面

TblInterval 

LowNumber HighNumber 
    1  50 
50  150 
150  200 
+0

好工作,但我不希望有界限的表。你可以重写没有边界表的好查询吗? – Arian

+0

@Arian更新回答 – DhruvJoshi

+0

That Works谢谢 – Arian

1

您可以使用case语句,使文件大小范围然后通过像这样的计数得到百分比

select a.range as FileSize, (Count(*)* 100/(Select Count(*) From MyTable)) as Percentage 
from (
select case 
when FileSize between 1 and 50 then '1-50' 
when FileSize between 50 and 150 then '50-150' 
when FileSize between 150 and 200 then '150-200' end as range 
from MyTable) a 
group by a.range 
+0

伟大的工作,但结果没有排序和'FileSize'订单没有工作。我怎样才能整理它... – Arian

+0

所有我能想到的是添加“1)1-50,2)50-150”而不是“1-50,50-150”,因为它们是字符串而不是数字 – Pream

0

可以连同分区通过使用AVG:

select distinct 
case 
when FileSize between 1 and 50 then '1-50' 
when FileSize between 50 and 150 then '50-150' 
when FileSize between 150 and 200 then '150-200' end as range 
, avg(FileSize) OVER (PARTITION BY (select 
            case when filesize between 0 and 50 then 1 
            when filesize between 50 and 150 then 2 
            when filesize between 150 and 200 then 3 
            end)) as percentage 
from mytable 
+0

对不起它没有产生我的愿望结果 – Arian

1
CREATE TABLE #A 
(
FILENAME INT,   FILESIZE INT 
) 
INSERT INTO #A VALUES 
(1,33), 
(2,198), 
(3,10), 
(4,127), 
(5,85), 
(6,23), 
(7,105), 
(8,158), 
(9,78), 
(10,90) 

SELECT RANGE,COUNT(*)*100/(SELECT COUNT(*) FROM #A) AS PERCENTAGE 
FROM ( 
SELECT *,CASE 
WHEN FILESIZE BETWEEN 1 AND 50 THEN '1-50' 
WHEN FILESIZE BETWEEN 50 AND 150 THEN '50-150' 
WHEN FILESIZE BETWEEN 150 AND 200 THEN '150-200' END AS RANGE 
FROM #A) A 
GROUP BY A.RANGE 
ORDER BY CASE WHEN RANGE = '1-50' THEN 1 
       WHEN RANGE ='50-150' THEN 2 
       WHEN RANGE ='150-200' THEN 3 
            END 

输出

RANGE PERCENTAGE 
1-50 30 
50-150 50 
150-200 20