筆記-在SQL查詢中計算所佔百分比
5 |
最近遇到的小需求,要計算資料表中某一數字欄位所佔百分比,例如:
ItemId GroupId CostAmt ------ ------- -------- X1000 A 50 X1001 A 250 X1002 A 200 X1003 B 200 X1004 B 300
目標是要由以上資料算出X1000佔全部成本5%,X1001佔25%... 等百分比資訊。另外則還要再進一步分組,算出各ItemId佔該組總成本的百分比,例如: X1000佔A群組成本總和的10%,X1001佔50%,X1002佔40%、而X1003佔B群組的40%,X1004佔60%。
發現Oracle有個好用的函數ratio_to_report()可輕鬆取得佔全部及佔各組總和的百分比:
SELECT ItemId, GroupId, CostAmt,
ratio_to_report(CostAmt) over () as Ratio
FROM Cost
SELECT ItemId, GroupId, CostAmt,
ratio_to_report(CostAmt)
over (PARTITION BY GroupId) as Ratio
FROM Cost
原本想在SQL Server找到對應的簡便寫法,但並無所獲。目前想到使用T-SQL產生相同結果的寫法如下:
SELECT ItemId, GroupId, CostAmt, CostAmt/X.CostSum AS Ratio
FROM Cost, (SELECT SUM(CostAmt) As CostSum FROM Cost) X
SELECT ItemId, X.GroupId, CostAmt, CostAmt/Y.CostSum AS Ratio
FROM Cost X JOIN (
SELECT GroupId, SUM(CostAmt) CostSum FROM Cost
GROUP BY GroupId
) Y ON X.GroupId = Y.GroupId
大家如有其他點子,歡迎提供!
[2012-02-14補充]感謝網友Billy補充,原來在SQL 2005起就有SUM() OVER能做到跟ORACLE ratio_to_report()完全相同的效果,SQL Server沒讓我失望,呵!
SELECT ItemId, GroupId, CostAmt,
CostAmt/SUM(CostAmt) OVER () AS Ratio
FROM Cost
SELECT ItemId, GroupId, CostAmt,
CostAmt/SUM(CostAmt) OVER (PARTITION BY GroupId) AS Ratio
FROM Cost
Comments
# by NO.18
在下一代的SQL Server 2012有新語法可以操作 http://msdn.microsoft.com/zh-tw/library/ms189461(v=SQL.110).aspx http://www.dotblogs.com.tw/ian/archive/2011/11/25/59563.aspx
# by NO.18
在下一代的SQL Server 2012有新語法可以操作 http://msdn.microsoft.com/zh-tw/library/ms189461(v=SQL.110).aspx http://www.dotblogs.com.tw/ian/archive/2011/11/25/59563.aspx
# by Billy
我想到的 SQL Server 解法使用的是windowing function: http://sqlfiddle.com/#!3/0541d/5 SELECT ItemId, GroupId, CostAmt, CostAmt/Sum(CostAmt) over () AS Ratio FROM Cost SELECT ItemId, GroupId, CostAmt, CostAmt/Sum(CostAmt) over (partition by groupID) AS Ratio FROM Cost
# by Jeffrey
to Billy, 哇!! 原來SQL早就有對應解決方案,汗顏居然沒找到,謝謝分享~~~
# by jain
好用,快筆記下來, 謝謝Billy !