Reputation: 13
I have a purchase table like below
customerID orderID item category purDate sold price
1 001 book stationary 1/1/2018 1 5
2 002 ball toys 1/1/2018 2 2
3 003 shirt cloth 1/1/2018 1 10
1 004 pen stationary 1/1/2018 5 3
4 005 shirt cloth 1/1/2018 2 10
5 006 card stationary 1/2/2018 15 2
6 007 tshirt cloth 1/2/2018 3 7
2 008 book stationary 1/3/2018 6 5
3 009 car toys 1/3/2018 2 4
1 010 book stationary 1/3/2018 4 5
4 011 ball toys 1/4/2018 2 2
6 012 pen stationary 1/4/2018 2 3
7 013 notebk stationary 1/4/2018 2 3
and I would like to query the best selling item for each day and category using MySQL so the query result would look like
purDate category item total revenue
1/1/2018 stationary pen 5 15
1/1/2018 toys ball 2 4
1/1/2018 cloth shirt 3 30
1/2/2018 stationary card 15 30
1/2/2018 cloth tshirt 3 21
1/3/2018 stationary book 10 50
1/3/2018 toys car 2 8
1/4/2018 toys ball 2 4
1/4/2018 stationary pen 2 6
1/4/2018 stationary notebk 2 6
I've checked other related topics on stackoverflow but couldn't find what I'm looking for. I am trying to use window function with aggregate functions, but keep failing.
SELECT purDate, category, item, total, revenue
FROM (SELECT purDate, category, item, SUM(sold) AS total, sold * price AS revenue,
RANK() OVER(PARTITION BY purDate, category ORDER BY SUM(sold) DESC) AS rank
GROUP BY 1,2,3) q
WHERE q.rank = 1
Thank you for your help in advance.
Upvotes: 0
Views: 66
Reputation: 37507
You miss a FROM
in your inner query. And you missed to also group by price
and to build the revenue
as sum(sold) * price
. Other than that you were absolutely on the right path.
SELECT purdate,
category,
item,
total,
revenue
FROM (SELECT purdate,
category,
item,
sum(sold) total,
sum(sold) * price revenue,
rank() OVER (PARTITION BY purdate
ORDER BY sum(sold) DESC) r
FROM purchase
GROUP BY purdate,
category,
item,
price) x
WHERE r = 1
ORDER BY purdate;
Upvotes: 2
Reputation: 561
Dont be afraid to break what you are trying to accomplish into multiple steps instead of one gigantic query.
Create table bleach select
pur_date, max(sold) as max_sold,
'' as total_rev
from your_table group by
pur_date;
Alter table bleach add
index(pur_date);
Alter table bleach add index
(max_sold);
Select a.* from your_table a,
bleach b where
a.pur_date=b.pur_date and
a.max_sold=b.max_sold;
Update bleach set
total_rev=sold*price
Drop table bleach;
Upvotes: 1