Reputation: 1176
I have a sales table from which I select the total sales per month , highest sale , number of sale for all the months in the current year, using
select monthname(date),sum(amt_c),MAX(amt_c)
from sales where year(date)= year(now())
group by monthname(date) ;
I want to also select the customer who has done the highest purchase , i.e the customer correponding to the MAX(amt_c).
amt_c is the purchase done by the customer,
Upvotes: 1
Views: 1990
Reputation: 13248
select v.monthname,
v.sum_amt_c,
v.max_amt_c,
count(s.amt_c) as num_of_amounts,
group_concat(s.cust) as customers
from (select monthname(date) as monthname,
sum(amt_c) as sum_amt_c,
max(amt_c) as max_amt_c
from sales
where date between concat(year(now()), '-01-01') and concat(year(now()), '-12-31')
group by monthname(date)) v
join sales s
on v.max_amt_c = s.amt_c
and v.monthname = monthname(s.date)
and s.date between concat(year(now()), '-01-01') and concat(year(now()), '-12-31')
group by v.monthname, v.sum_amt_c, v.max_amt_c
order by month(s.date)
This is similar to Andomar's answer however it provides the following benefits:
If your DATE field is indexed (it should be) the above query will use that index. You should not have criteria on a date field with a function applied to it. MySQL does not support function based indexes, so it is a given that year(date) is not indexed. date may be indexed, however.
This sorts the results by month # (1-12) but shows the month name.
In the event that the same 2+ customers are tied, this will list all of them, and show only one row for that month. You would otherwise potentially have 2, 3, 4+ rows for a single month in the event of a tie. This is done via MySQL's GROUP_CONCAT function.
Upvotes: 1
Reputation: 238166
One way is a filtering join:
select filter.mn
, filter.sum_sales
, filter.max_sales
, sales.cust
from (
select monthname(date) as mn
, sum(amt_c) as sum_sales
, max(amt_c) as max_sales
from sales
where year(date) = year(now())
group by
mn
) filter
join sales
on monthname(sales.date) = filter.mn
and sales.amt_c = filter.max_sales
For more approaches, browse the greatest-n-per-group tag.
Upvotes: 2