Reputation: 357
Im trying to find a way to group my results into 3 groups that are predefined 0-33%, 34-66% and 67-100%. The calculation is already being set as "Depletion". I want to group the top, middle and bottom of this column into the three different groups. Here is the query I'm using from multiple tables.
I assume I need to find the highest value in the SELECT first so that I can calculate the percentage, but I cant seem to find a way to do that. From there I dont know how to group the items based on percent.
SELECT l.name AS Location, i.name AS ItemName, li.par, COUNT(*) AS Sales, li.par - COUNT(*) AS Depletion
FROM shoppingcartdetail AS o INNER JOIN
item AS i ON i.id = o.itemid INNER JOIN
location AS l ON o.locationid = l.id INNER JOIN
location_item AS li ON i.id = li.itemid
WHERE (CONVERT(datetime, o.created_date_time, 101) BETWEEN GETDATE() - l.service_interval AND GETDATE()) AND (o.locationid = 1)
GROUP BY i.barcode, i.name, l.name, li.par
Sample result
ItemName | avgshelflife | unitcost | par | Sales | Depletion
Dr. Pepper Bottle 20 oz | 90 | 0.83 | 70 | 31 | 39
Mountain Dew Bottle 20 oz| NULL |NULL | 70 | 27 | 43
Coke Can 12 oz | NULL |NULL | 30 | 22 | 8
M&M's Peanut 1.74 oz | 90 | 0.60 | 66 | 14 | 52
Dr. Pepper Can 12 oz | 180 | 0.38 | 30 | 13 | 17
Where M&M's Peanut 1.74 oz would by the 100% threshold with the highest Depletion of 52. Items would be grouped into the three groups with a new column added.
In this case: Y=%*52(Depletion of M&M's Peanut 1.74 oz)
Group0-30% is 0-17
Group31-66% is 18-34
Group66-100% is 35-52
Results
Group0-30% Coke Can 12 oz
Group31-66% Dr. Pepper Can 12 oz
Group66-100% Dr. Pepper Bottle 20 oz, Mountain Dew Bottle 20 oz, M&M's Peanut 1.74 oz
Thanks in advance!
Upvotes: 0
Views: 86
Reputation: 28900
You could also declare a function which calculates percent based on row number..below is the logic ,you may want to refine as per your needs..further point to note is some rows may say zero percent,but the rows returned are inline with top percent clause..
Orderid is a PK in my demo,you can change it a unique number or PK in your case
Alter function dbo.getpercent
(@orderid as int
)
returns int
as
begin
declare @pcnt int
;with cte
as
(
select row_number() over (order by orderid) as rn,orderid
from sales.orders)
select @pcnt=(cast(rn as float)/830)*100 from cte
where orderid=@orderid
return @pcnt
end
select dbo.getpercent(orderid) ,* from sales.orders
order by orderid
Upvotes: 0
Reputation: 1138
As I understand your question you want to display "Depletion" which is percentage that you need to display in group. If this so you can use like this.
select *,CASE
WHEN (Depletion < 34) THEN
'Group0-30%' + ItemName
ELSE
CASE
WHEN (Depletion < 67) THEN
'Group31-66%' + ItemName
ELSE
'Group66-100%' + ItemName
END
END from (
SELECT l.name AS Location, i.name AS ItemName, li.par, COUNT(*) AS Sales, li.par - COUNT(*) AS Depletion
FROM shoppingcartdetail AS o INNER JOIN
item AS i ON i.id = o.itemid INNER JOIN
location AS l ON o.locationid = l.id INNER JOIN
location_item AS li ON i.id = li.itemid
WHERE (CONVERT(datetime, o.created_date_time, 101) BETWEEN GETDATE() - l.service_interval AND GETDATE()) AND (o.locationid = 1)
GROUP BY i.barcode, i.name, l.name, li.par) t
If not like that then please provide with data for better understand.
Thanks,
Upvotes: 1
Reputation: 28900
this works(ugly though),the idea is to use top percent and then do the rest,i have used sales.orders table for demo purposes,but the idea remains the same..
step1: get all percentages into three temp tables,i have used three different temp tables due to identity col and laziness,you can do it with one
select top 33 percent * ,'37 pcnt' as 'pcnt' into #temp1 from sales.orders order by orderdate desc
select top 67percent * ,'67 pcnt' as 'pcnt' into #temp2 from sales.orders order by orderdate desc
select * ,'100 pcnt' as 'pcnt' into #temp3 from sales.orders
now next step is the place where we get data..
with cte
as
(
select * from #temp
union all
select * from
(
select * from #temp1 t1 where not exists(select 1 from #temp t2 where t2.orderid=t1.orderid)
)c
)
select * from cte
union all
select * from
(
select * from #temp3 t3 where not exists(select 1 from cte where cte.orderid=t3.orderid)
)b
Upvotes: 0