Percentage from Total SUM after GROUP BY SQL Server
You don't need a cross join
. Just use window functions:
SELECT P.PersonID, SUM(PA.Total),
SUM(PA.Total) * 100.0 / SUM(SUM(PA.Total)) OVER () AS Percentage
FROM Person P JOIN
Package PA
ON P.PersonID = PA.PackageFK
GROUP BY P.PersonID;
Note that you do not need the JOIN
for this query:
SELECT PA.PersonID, SUM(PA.Total),
SUM(PA.Total) * 100.0 / SUM(SUM(PA.Total)) OVER () AS Percentage
FROM Package PA
GROUP BY PA.PersonID;
SQL Server does integer division. I do such calculations using decimal numbers so they make more sense.
Here is a SQL Fiddle, with two changes:
- The database is changed to SQL Server.
- The total is stored as a number rather than a string.
You can use Common table Expression...
;with cte as(
select P.PersonID,SUM(cast(PA.Total as int))Total from Package PA join Person P on P.PersonID = PA.PackageFK GROUP BY P.PersonID
)
select PersonId,Total,cast (Total * 100 / t.GrandTotal as varchar) + '%' [Percentage] from cte cross join(select SUM(cast(Total as int)) as GrandTotal from Package)t
Try this below code
;With cte(PersonID ,Total)
AS
(
SELECT 1 ,75 UNION ALL
SELECT 2 ,75 UNION ALL
SELECT 3 ,15 UNION ALL
SELECT 4 ,15 UNION ALL
SELECT 5 ,60 UNION ALL
SELECT 6 ,60
)
SELECT PersonID,
Total,
CAST(CAST((MAX(total)OVER(partition BY personid ORDER BY total)*100.0/
MaxSum) AS INT)AS VARCHAR(5))+ '%' AS Percentage
FROM (SELECT personid,
total,
stotal,
Max(stotal)
OVER(
ORDER BY stotal DESC) AS MaxSum
FROM (SELECT personid,
total,
Sum(total)
OVER(
ORDER BY personid) AS STotal
FROM Cte)dt
GROUP BY dt.personid,
dt.total,
dt.stotal)dt2
ORDER BY dt2.personid ASC
Result
PersonID Total Percentage
------------------------------
1 75 25%
2 75 25%
3 15 5%
4 15 5%
5 60 20%
6 60 20%