2013-05-21 35 views
1
col1 col2 
b 5 
b 10 
b 20 
b 30 
b 200 
b 300 

選擇mytable的前50個COL2是給如何獲得前 'n' 的百分比值

col2 
5 
10 
20 

而實際50%是不同的

col1 col2 Total(of col2) div(col2/total) CumulativeAddition % 
b 5   565     0.01   0.01   1% 
b 10   565     0.02   0.03   3% 
b 20   565     0.04   0.06   6% 
b 30   565     0.05   0.12   12% 
b 200   565     0.35   0.47   47% 
b 300   565     0.53   1.00   100% 

正如你可以看到它是

5 1% 
10 3% 
20 6% 
30 12% 
200 47% 

我使用正確的SQL函數嗎?

+2

'TOP 50 PERCENT'只會給你排名前50%**。即6中的3個。 –

+0

我認爲最高的50%返回行數的50%。我認爲那不是你想要的? – Andrew

+0

@MartinSmith,應該是一個答案 – WiiMaxx

回答

1

前面已經提到的,top語法並不做你想做的。

您需要累積和。唉,在SQL Server 2012中支持此操作,但不支持SQL Server 2008.

爲了便於閱讀,我更喜歡使用相關子查詢來獲取累計和。查詢的其餘部分只是算術運算:

select col1, col2, TotalCol2, CumSumCol2, 
     CumSumCol2/cast(TotalCol2 as float) as CumPercent 
from (select col1, col2, 
      sum(col2) over (partition by col1) as TotalCol2, 
      (select sum(col2) from mytable t2 where t2.col1 = t.col1 and t2.col2 <= t.col2 
      ) as CumSumCol2 
     from mytable t 
    ) t 
where CumSumCol2/cast(TotalCol2 as float) < 0.5 
3

在SQL Server 2012中,可以使用窗口函數來計算運行總和。累計百分比是運行總和除以整個表的總和。因爲SQL Server不允許where子句中使用的窗函數

select * 
from (
     select * 
     ,  100.0 * sum(col2) over (order by col2)/sum(col2) over() 
        as perc 
     from dbo.YourTable 
     ) SubQueryAlias 
where perc <= 50.0 

子查詢是必需的。

Example at SQL Fiddle.


對於舊版本的SQL Server,計算運行總和更多的工作。如果您在col2中有聯繫,則必須提供區分它們的方法。

select * 
from (
     select cur.col1 
     ,  cur.col2 
     ,  100.0 * sum(running.col2)/total.total as perc 
     from dbo.YourTable cur 
     join (
       select col2 
       from dbo.YourTable prev 
       ) running 
     on  running.col2 < cur.col2 
     cross join 
       (
       select sum(col2) as total 
       from YourTable 
       ) total 
     group by 
       cur.col1 
     ,  cur.col2  
     ,  total.total 
     ) SubQueryAlias 
where perc <= 50.0 

Example at SQL Fiddle.

+0

這個查詢拋出錯誤「命令附近的語法不正確」。 – Gokul

+0

你正在使用哪個版本的SQL Server? ? – Andomar