Query Explanation:
This MySQL query calculates a 7-day rolling total and average of the amount spent by customers over a series of distinct dates (visited_on) from the Customer table. The query is broken into two main parts:
1. Common Table Expression (CTE) D
The first part of the query defines a Common Table Expression (CTE) named D which selects distinct visited_on dates from the Customer table.
sql
WITH D AS (
SELECT DISTINCT
visited_on
FROM
Customer
WHERE
visited_on >= (
SELECT
DATE_ADD(MIN(visited_on), INTERVAL 6 DAY)
FROM
Customer
)
)
- Purpose of the CTE:
- This part is creating a list of distinct visit dates (
visited_on), starting from 6 days after the earliest visit date recorded in the Customer table. - Explanation:
MIN(visited_on): Finds the earliest visit date in the Customer table.DATE_ADD(MIN(visited_on), INTERVAL 6 DAY): Adds 6 days to this earliest date, so the query begins from this point.SELECT DISTINCT visited_on: Ensures that only unique visited_on dates are selected, avoiding duplicates.- The
WHERE clause filters out any visit dates before the adjusted starting date (6 days after the earliest visit).
2. Main Query (Aggregating Amount and Average)
The main part of the query calculates the total (amount) and the 7-day rolling average of the amount spent by customers. It uses the LEFT JOIN to include visits from Customer within a 7-day window around each date in the D CTE.
sql
SELECT
D.visited_on,
SUM(Customer.amount) amount,
ROUND(SUM(Customer.amount)/7, 2) average_amount
FROM
D
LEFT JOIN
Customer ON (DATEDIFF(D.visited_on, Customer.visited_on) BETWEEN 0 AND 6)
GROUP BY
1;
- Join Operation:
LEFT JOIN Customer ON (DATEDIFF(D.visited_on, Customer.visited_on) BETWEEN 0 AND 6):- Joins each date in
D with all visited_on dates from Customer that fall within a 7-day range. DATEDIFF(D.visited_on, Customer.visited_on) calculates the difference between the dates.- The condition
BETWEEN 0 AND 6 ensures the difference is within the 7-day window (including the date itself). - Aggregation:
SUM(Customer.amount) amount: Sums up the amount spent by customers for each 7-day period.ROUND(SUM(Customer.amount)/7, 2) average_amount: Computes the average amount spent per day over the 7-day period. It divides the total amount by 7 (days) and rounds the result to 2 decimal places.- Grouping:
GROUP BY 1: Groups the results by the first column in the SELECT statement, which is the visited_on date from D.
What Does This Query Do?
The query calculates the total and average amount spent by customers in each rolling 7-day period, starting from 6 days after the earliest visit recorded in the Customer table.
- The rolling sum represents the total amount spent during the past 7 days (including the current day).
- The rolling average is the average of the amounts spent per day over the last 7 days.
Example Workflow:
- Let's assume the
Customer table contains the following records:
idvisited_onamount12023-01-015022023-01-027032023-01-033042023-01-046052023-01-059062023-01-068072023-01-0710082023-01-08110
- If the earliest
visited_on is 2023-01-01, then the query starts at 2023-01-07 (6 days after the earliest visit). - The query will then calculate the total and average amounts for every 7-day window starting from 2023-01-07.
Final Result:
The final result will include:
visited_on: The start date of the 7-day rolling window.amount: The sum of amount for the last 7 days (including the current day).average_amount: The average of amount over the 7-day period.
Summary:
- CTE (D): Selects distinct
visited_on dates starting from 6 days after the earliest visited_on. - Main Query: Joins these dates with the
Customer table and calculates the 7-day total and average amount for each distinct visited_on date.