how to calculate percent of total within group by statement?

萝らか妹 提交于 2019-12-19 07:49:24

问题


I have a table with 1 record per sale per salesperson per day

NAME  DATE
joe   1-1-13
joe   1-1-13
joe   1-1-13
dave  1-1-13
joe   1-2-13

I used this to create & populate the table

create table #sales (name varchar(10), salesdate date )
insert into #sales (name, salesdate) 
values ('joe', '01-01-2013'), ('joe','01-01-2013'), 
       ('joe', '01-01-2013'), ('dave','01-01-2013'),  
         ('joe','01-02-2013')

I want a query to pull up the percent of each salesperson's sales by day

(for example on 1-1-13 Joe sold 3 units out of 4 total for the day (75%) but I dont know how the SQL can pull up the daily total of all sales for the day regardless of salesperson

This is as close as I got.

select name, salesdate, count(*) as "dailyTotal"
from #sales
group by name, salesdate

How can I include the daily total that is so that it can be used in calculating percent total for the day?


回答1:


Not the most elegant way to do it, but you can try this -

select [name],[salesdate], COUNT(*) as dayTotal, 
SUM(COUNT(*)) over() as AllSales, 
(COUNT(*) * 1.0) / SUM(COUNT(*)) over() as dayPercent
FROM [dbo].[sales]
group by [name], [salesdate]

I removed the # in your table name. Btw, this code depends on OVER() clause. You can find out how to truncate the excess zeros yourself.

name    salesdate   dayTotal    AllSales    dayPercent
dave    2013-01-01  1           5           0.200000000000
joe   2013-01-01    3           5           0.600000000000
joe   2013-01-02    1           5           0.200000000000

HTH.

If that query looks too complicated to you, then look at this one first. It will give you an idea of what I am trying to do.

select [name],[salesdate], COUNT(*) as dayTotal, 
SUM(COUNT(*)) over() as AllSales
FROM [dbo].[sales]
group by [name], [salesdate]



回答2:


The most upvoted answer doesn't seem correct.

The OP has the expected answer

for example on 1-1-13 Joe sold 3 units out of 4 total for the day (75%)

and yet the upvoted answer shows 60%.

Instead of summing over all data it should be partitioned by day, here's a better example:

select [name],[salesdate], COUNT(*) as dayTotal, 
SUM(COUNT(*)) over(PARTITION BY salesdate) as AllDaySales, 
(COUNT(*) * 1.0) / SUM(COUNT(*)) over(PARTITION BY salesdate) as dayPercent
FROM [dbo].[sales]
group by [name], [salesdate]



回答3:


Use a nested query to get the daily total:

BEGIN

    create table #sales (name varchar(10), salesdate date )

    insert into #sales (name, salesdate) values 
        ('joe', '01-01-2013'), 
        ('joe', '01-01-2013'), 
        ('joe', '01-01-2013'), 
        ('dave', '01-01-2013'),  
        ('joe', '01-02-2013'),
        ('dave', '01-02-2013')

    SELECT name, salesdate, COUNT(*) AS personDailyTotal, MAX(dailyTotal) AS dailyTotal, 
        (COUNT(*) * 100.0) / MAX(dailyTotal) AS [Percent]
    FROM #sales
    INNER JOIN (
        SELECT salesdate as [day], COUNT(*) as dailyTotal 
        FROM #sales 
        GROUP BY salesdate
    ) AS [Total] ON salesdate = [day]
    GROUP BY name, salesdate

END



回答4:


-- Use Below Query

select T1.salesdate, name ,convert(numeric(18,2),convert(decimal,count(*)) * 100 / T2.total) as percentage from #sales T1
     inner join (
     select salesdate,count(*) as total from #sales group by salesdate
     ) as T2
     on T1.salesdate = T2.salesdate
     group by name,T1.salesdate,T2.total


来源:https://stackoverflow.com/questions/20532187/how-to-calculate-percent-of-total-within-group-by-statement

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!