Reputation: 1409
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?
Upvotes: 5
Views: 19487
Reputation: 36
-- 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
Upvotes: 0
Reputation: 127
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]
Upvotes: 7
Reputation: 20560
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
Upvotes: 2
Reputation: 1488
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]
Upvotes: 11