how to calculate percent of total within group by statement?

前端 未结 4 1908
野的像风
野的像风 2021-01-13 04:19

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

相关标签:
4条回答
  • 2021-01-13 04:58

    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
    
    0 讨论(0)
  • 2021-01-13 05:04

    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]
    
    0 讨论(0)
  • 2021-01-13 05:04

    -- 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
    
    0 讨论(0)
  • 2021-01-13 05:11

    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]
    
    0 讨论(0)
提交回复
热议问题