Reputation: 97
I've worte SQL query for average duration from order date to sent date. It is for my e-commerce project. But I want compare it with previous month.
SELECT AVG(DATEDIFF(os.time, o.ordered)) AS average_value,
YEAR(os.time) AS groupYear,
MONTH(os.time) AS groupMonth
FROM orders AS o
LEFT JOIN order_status_history os ON o.id = os.order_id
WHERE os.status_id = 2
GROUP BY groupyear, groupmonth
I want in select average value from previous month too. I've try LEFT JOIN with ON -1 month. But it showed bad values, so it's not probably right way.
o.ordered and os.time are both Datetime.
Thanks everyone for help.
Upvotes: 2
Views: 160
Reputation: 6276
My solution is to create a view for the subquery first:
CREATE VIEW MonthlyValue AS
SELECT YEAR(os.time) AS groupYear,
MONTH(os.time) AS groupMonth,
os.status_id,
AVG(DATEDIFF(os.time, o.ordered)) AS average_value
FROM orders AS o
LEFT JOIN order_status_history os ON o.id = os.order_id
GROUP BY groupyear, groupmonth,os.status_id;
Then you can use the view to get information of the previous and current month:
SELECT tc.groupYear as year, tc.groupMonth as month, tp.groupYear prevYear, tp.groupMonth as prevMonth,
mv.average_value, mvprev.average_value, mv.average_value - mvprev.average_value as difference
FROM MonthlyValue mv join MonthlyValue mvprev on mv.status_id=mvprev.status_id and
(mv.groupYear=mvprev.groupYear and mvprev.groupMonth=mv.groupMonth-1 or
mv.groupMonth=1 and mvprev.groupMonth=12 and mvprev.groupYear=mv.groupYear-1)
WHERE mv.status_id = 2;
Upvotes: 0
Reputation: 15057
this is not tested. if it not work you can post some sampledata and create statements
SELECT AVG(DATEDIFF(os.time, o.ordered)) AS average_value,
YEAR(os.time) AS groupYear,
MONTH(os.time) AS groupMonth
FROM orders AS o
LEFT JOIN order_status_history os ON o.id = os.order_id
LEFT JOIN (
SELECT AVG(DATEDIFF(os.time, o.ordered)) AS average_value,
YEAR(os.time) AS groupYear,
MONTH(os.time) AS groupMonth
FROM orders AS o
LEFT JOIN order_status_history os ON o.id = os.order_id
WHERE os.status_id = 2
GROUP BY DATE_FORMAT(os.`time`, '%Y%my')
) AS l ON l.groupYear = YEAR(SUBDATE(os.time, INTERVAL 1 MONTH)) AND l.groupMonth = MONTH(SUBDATE(os.time, INTERVAL 1 MONTH))
WHERE os.status_id = 2
GROUP BY DATE_FORMAT(os.`time`, '%Y%my');
Upvotes: 1