How to Aggregate Weighted averages fields at different levels of granularity? - mysql

I am calculating weighted formula for a field as sum(revenue)/ Sum(qty) and this is as per the below query. Now I will be creating a view that would store these results as I shown in code below.
My question is, if I select this w_revenue out of the view and want to see per year, how will I aggregate to show it per year? See desired outputs.
select month,item, sum(revenue)/ Sum(qty) as w_revenue,
year
from my_revenue_table
group by month, year,item;
create view xyz as
select month,item, sum(revenue)/ Sum(qty) as w_revenue,
year
from my_revenue_table
group by month, year,item;
select w_revenue
from xyz.
How do I do this so as to aggregate this per year?
Year Month Item Revenue Qty Sum(revenue)/Sum(Qty)
2019 Mar A 10 2 5
2019 Mar B 30 3 10
2019 Feb C 50 1 50
2019 Feb D 20 2 10
Expected value if I see per year:
Year Sum(revenue)/Sum(Qty)
2019 13.75 (10+30+50+20)/(2+3+1+2)

group on by year then create another view as
create view abc as
select sum(revenue)/ Sum(qty) as w_revenue, year
from my_revenue_table
group by year;
and call
select * from xyz union all
select null, null, a.* from abc a
to combine them, if I understood you correctly.
or revenue per year repeating at every row as
select x.*,
(select w_revenue
from abc
where year = x.year) as w_revenue_year
from xyz x

You cannot do the aggregation you want from the view. You don't have enough information.
If you change the view to something like this:
create view xyz as
select year, month, item,
sum(revenue)/ Sum(qty) as w_revenue,
sum(qty) as total_qty
from my_revenue_table
group by month, year, item;
Then you can aggregate the results as:
select year, sum(w_revenue * total_qty) / sum(total_qty)
from xyz
group by year;
EDIT:
Or just modify the view to have the information you want:
create view xyz as
select year, month, item,
sum(revenue)/ Sum(qty) as w_revenue,
sum(qty) as total_qty,
(sum(sum(revenue)) over (partition by year, item) /
sum(sum(qty)) over (partition by year, item)
) as w_revenue_year
from my_revenue_table
group by month, year, item;

Related

Getting the Monthwise count from date column in MySQL

I have a table that consists of the following data, I would like to know whether it is possible to get a Month (i.e Jan, Feb) wise count of Reservations that happened and also Month wise count for each location.
PNR
Location
Reservation Date
Passenger Name
Travel Date
PNR81239087
Mumbai
2019-10-01 12:19:00
Ram
2019-11-06 15:59:00
PNR81239090
Kerala
2019-10-01 15:18:00
Kannan
2019-12-03 19:18:00
PNR812390199
Mumbai
2019-10-01 17:19:00
Ram
2019-11-01 18:39:00
For example,
Month Wise Count (including all locations) should look something like this,
Month
Count
October-2019
3
Monthwise count for each location:
Month
Count
Location
October-2019
2
Mumbai
October-2019
1
Kerala
I think this will work for you
Month Wise Count (including all locations) :
select MONTHNAME(Reservation_Date) as Month, count(*)
from yourTable
group by MONTHNAME(Reservation_Date)
Monthwise count for each location :
select MONTHNAME(Reservation_Date) as Month, count(*), Location
from yourTable
group by MONTHNAME(Reservation_Date), Location
EDIT IN QUESTION :
Changed to Group by Year and Month in one column:
Month Wise Count (including all locations) :
select concat(MONTHNAME(Reservation_Date),'-',Year(Reservation_Date)) as Month-Year,
count(*) as Count
from yourTable
group by concat(MONTHNAME(Reservation_Date),'-',Year(Reservation_Date))
Monthwise count for each location :
select concat(MONTHNAME(Reservation_Date),'-',Year(Reservation_Date)) as Month-Year,
count(*) as Count, Location
from yourTable
group by concat(MONTHNAME(Reservation_Date),'-',Year(Reservation_Date)), Location
You can use this :
/*Location-wise*/
SELECT DATENAME(MONTH, ReservationDate) as [Month],
COUNT(*) AS Count,
Location
FROM Temp
GROUP BY DATENAME(MONTH, ReservationDate), Location
ORDER BY Location DESC
/*All locations*/
SELECT DATENAME(MONTH, ReservationDate) as [Month],
COUNT(*) AS Count
FROM Temp
GROUP BY DATENAME(MONTH, ReservationDate)
You can see this working here : All locations and Locations-wise

Average sales in the Nth month of the customer journey

I need to find average sales by month of the customer. For example one customer bought in Jan2020 some products... then in Feb... so jan becomes 1st month and feb 2nd for the customer.
Similarly other customer buys 1st time in Apr'20 and next time in June'20..... so avg sales for 1st Mon(Apr) and 2nd month (Avg of Apr and Jun)
Expected outcome:
CustID Month Avg_sales
You can use window functions to get the first date. And then arithmetic. Here is one method:
select custid, year(date) * 12 + month(date) - (year(first_date) * 12 + month(first_date)) as diff,
avg(sales) as avg_sales
from (select t.*,
min(date) over (partition by custid) as first_date
from t
) t
group by custid, diff

GROUP BY select within SELECT

I have one table which i want to select some rows and group them by date. the problem is when i'm selecting within my select that row appear to not grouped by date, see the example:
SELECT date, SUM(price), (SELECT SUM(price), date FROM expense WHERE
user = 'Catherine') as cprice FROM expense GROUP BY date
it does not grouping cprice, it will sum all Catherine prices and doesn't group it by date, by the way I tried GROUP BY date into the within select but doesn't work either.Any suggestion?
expense table:
id user price date
1 Frank 20 2014
2 Catherine 10 2013
3 Catherine 20 2014
thank you
You can try this:
SELECT
date,
SUM(price) as totalPrice,
SUM(IF(user='Catherine', price, 0)) as cprice
FROM expense
GROUP BY date
If you want both price together then you can try this:
SELECT
date,
SUM(price) + SUM(IF(user='Catherine', price, 0)) as cprice
FROM expense
GROUP BY date
try this query, it select * row where user = 'Catherine' and groups them by date
SELECT
date,
SUM(price)
FROM expense
WHERE user = 'Catherine'
GROUP BY date
Try Using Case Statement:(I'm Not Familiar With MySQL :( )
Not Sure,Like:
SELECT
date,
SUM(price) as totalPrice,
SUM(Case When user='Catherine' Then price Else 0 End CASE;) as catherine_price
FROM expense
GROUP BY date
You probaby can solve it using a two selects and pull out the data you need using a loop.

SQL query to return amount of sales and amount of salespersons

4am here... this is driving me nuts. I have a report table:
id_report
invoice_date
id_user (sales person)
I need to display, by month, how many items were sold, and also how many salespersons sold those items. For example, in january user 3 sold 10 items and user 8 sold 7 items, that should return:
date | items | salespersons
2014-01 | 17 | 2
This was my first approach, but that doesn't bring me the 3rd column:
SELECT DATE_FORMAT(invoice_date, "%Y-%m") AS date, COUNT(*) AS items,
FROM report
GROUP BY date
Thanks!
In your query you haven't add the third column. Try this:
SELECT DATE_FORMAT(invoice_date, "%Y-%m") AS date,
COUNT(*) AS items,
COUNT(DISTINCT id_user) AS salespersons
FROM report
GROUP BY date
Working demo: http://sqlfiddle.com/#!2/03e45/1
It's important to use the DISTINCT keyword, or you will have the same count as items.
SELECT
DATE_FORMAT(invoice_date, '%Y-%m') AS date,
COUNT(*) AS items,
COUNT(DISTINCT id_user) as sales_persons
FROM report
GROUP BY date
You need to add count( id_user ) as sales_persons.
This is not being selected.
SELECT
DATE_FORMAT(invoice_date, "%Y-%m") AS date,
COUNT(*) AS items,
count( id_user ) as sales_persons
FROM report
GROUP BY date
You are not asking for the third column in your query. Add COUNT(id_user) as salespersons. Do your query like this:
SELECT DATE_FORMAT(invoice_date, "%Y-%m") AS date, COUNT(*) AS items, COUNT(id_user) as salespersons FROM report GROUP BY date

selecting the month day and year from a transaction table

I want to create two queries for my table which has fields name,surname and amount paid,the first query should select the day,month and the amount paid,the second query should select a month,year in that year and the total amount paid in that month,lets say john paid on 2013-05-01, on 2013-05-03,while peter paid on 2013-04-08, i want the first query to output
month and day amount
05-01 200
05-03 400
04-08 50
and the second query should output:
month and year total
2013-05 600
2013-04 50
I know I can use the sum aggregate function to select the total but the tricky part is how to select the day and the month in the format above,
first query will be
SELECT DATE_FORMAT(date, "%m-%d") AS 'month and day',price as amount FROM `tablename`
and second query will be
SELECT DATE_FORMAT(date, "%Y-%m") AS 'month and year' , SUM(price) AS total FROM `tablename` GROUP BY YEAR(date), MONTH(date)