patternsqlMinor
MySQL: AVG of defined variable per month
Viewed 0 times
peravgmysqlmonthvariabledefined
Problem
I need help with the following code:
I now need the average login number / login count before purchase on a monthly basis.
For instance, the calculation should analyze the buys in January and calculate the average logins (max 1 per day) that were necessary for this purchase.
Could please somebody help me?
SELECT DISTINCT
userid
, count( userid ) as login_count
FROM
(
SELECT DISTINCT
userid
, date(FROM_UNIXTIME(date_time)) AS DAY
FROM xcart_login_history
WHERE status="success"
and (action ="login" or action = "autologin")
ORDER BY userid, DAY
) as login_days
WHERE login_days.DAY
This shows me the COUNT` of logins for individual users before purchasing. It is on purpose not returning more than one per day counted. I now need the average login number / login count before purchase on a monthly basis.
For instance, the calculation should analyze the buys in January and calculate the average logins (max 1 per day) that were necessary for this purchase.
Could please somebody help me?
Solution
Rewritten to only count logins after the last previous order:
-- Calculate the previous order date for each order
CREATE TEMPORARY TABLE Orders
(
OrderID INT NOT NULL PRIMARY KEY,
UserID INT NOT NULL,
OrderDate DATETIME NOT NULL,
Year YEAR NOT NULL,
Month TINYINT NOT NULL,
PreviousOrderDate DATETIME
)
INSERT INTO Orders (OrderID, UserID, OrderDate, Year, Month, PreviousOrderDate)
SELECT
O2.orderid,
O2.userid,
FROM_UNIXTIME(O2.date) AS OrderDate,
YEAR(FROM_UNIXTIME(O2.date)) AS Year,
MONTH(FROM_UNIXTIME(O2.date)) AS Month,
MAX(O1.date_time) AS PreviousOrderDate
FROM
xcart_orders AS O2
LEFT JOIN xcart_orders AS O1 ON O2.userid = O1.userid AND O1.date_time O.PreviousOrderDate OR O.PreviousOrderDate IS NULL) -- Only count logins from after the last previous order (if one exists)
AND L.status = 'success'
AND L.action IN ('login', 'autologin')
GROUP BY
O.OrderID, O.Year, O.Month
) AS X
GROUP BY
Year, Month
ORDER BY
Year, MonthCode Snippets
-- Calculate the previous order date for each order
CREATE TEMPORARY TABLE Orders
(
OrderID INT NOT NULL PRIMARY KEY,
UserID INT NOT NULL,
OrderDate DATETIME NOT NULL,
Year YEAR NOT NULL,
Month TINYINT NOT NULL,
PreviousOrderDate DATETIME
)
INSERT INTO Orders (OrderID, UserID, OrderDate, Year, Month, PreviousOrderDate)
SELECT
O2.orderid,
O2.userid,
FROM_UNIXTIME(O2.date) AS OrderDate,
YEAR(FROM_UNIXTIME(O2.date)) AS Year,
MONTH(FROM_UNIXTIME(O2.date)) AS Month,
MAX(O1.date_time) AS PreviousOrderDate
FROM
xcart_orders AS O2
LEFT JOIN xcart_orders AS O1 ON O2.userid = O1.userid AND O1.date_time < O2.date_time
GROUP BY
O2.orderid,
O2.userid,
O2.date
-- Calculate the average for each year and month
SELECT
Year, Month, COUNT(*) AS Orders, SUM(PreviousLogins) / COUNT(*) AS AvgPrevLogins
FROM
(
-- Get the number of previous logins for each order
SELECT
O.OrderID, O.Year, O.Month, COUNT(L.userid) AS PreviousLogins
FROM
Orders AS O
LEFT JOIN xcart_login_history AS L
ON O.UserID = L.userid
-- Filter logins here in the join rather than in a WHERE clause, or you exclude orders that HAVE no previous logins (in practice, such may not exist)
AND L.date < O.OrderDate
AND (L.date > O.PreviousOrderDate OR O.PreviousOrderDate IS NULL) -- Only count logins from after the last previous order (if one exists)
AND L.status = 'success'
AND L.action IN ('login', 'autologin')
GROUP BY
O.OrderID, O.Year, O.Month
) AS X
GROUP BY
Year, Month
ORDER BY
Year, MonthContext
StackExchange Database Administrators Q#20919, answer score: 2
Revisions (0)
No revisions yet.