简体   繁体   中英

MYSQL query to get new customers each week

I'm struggling with how I can get a report of new customers each week (those who have never ordered previously). The results should look as follows:

WEEK_ENDING_DATE   NEW_CUSTOMERS
----------------   -------------
2019-02-03         50
2019-02-10         60

My query does a Right Outer Join of old_orders and new_orders to find new customers (see query below).

I also have a helper table called my_calendars that helps me to group by week_end_date. The my_calendars table has rows containing each date in the year, the corresponding week_begin_date and week_end_date for that date. For example, for a date like 2019-02-15, the week_begin_date is 2019-02-11 and week_end_date is 2019-02-17 (Week is Mon - Sun, Format = YYYY-MM-DD). The helper table looks as follows:

DATE           WEEK_BEGIN_DATE      WEEK_END_DATE
----------     ----------------     -------------
2019-02-15     2019-02-11           2019-02-17
2019-01-08     2019-01-07           2019-01-13

Now, back to my query. I want to be able to find new customers each week. The problem I'm having is that I can't figure out how to place each week of the year in the query so as to compare the order dates. The old_orders are orders that took place before 'this week', and the new_orders are those that took place 'this week'. The query works fine when I use static dates, but I'm struggling to make the dates variable ie each week in the year. See my questions in the query where I'm having challenges.

SELECT 
    new_orders.week_end_date
    ,COUNT(DISTINCT new_orders.customer) AS new_customers       
FROM
      (SELECT * 
        FROM orders old
        INNER JOIN my_calendar cal ON cal.date = old.order_date
        #The line below works, but it's a static date of Feb 4. How do I replace it with each week in the calendar
        WHERE cal.week_end_date < '2019-02-04'
        #The commented line below does not work
        #WHERE cal.date < cal.week_end_date
      ) AS old_orders
RIGHT OUTER JOIN (SELECT * 
                  FROM order_items_view new
                  INNER JOIN my_calendar cal ON cal.date = new.order_date
                  #How do I replace the static dates below and compare with each week in the calendar  
                  WHERE cal.date BETWEEN '2019-02-04' and '2019-02-10'
                  #The commented line below didn't work
                  #WHERE cal.week_end_date = cal.week_end_date
                 ) AS new_orders
ON new_orders.customer = old_orders.customer
WHERE old_orders.customer IS NULL
GROUP BY new_orders.week_end_date

I would first use an aggregated subquery to compute the first order date of each customer, and then join the result with the calendar table :

SELECT
    c.week_end_date,
    COUNT(o.customer) AS new_customers
FROM
    my_calendar AS c
    LEFT JOIN (
        SELECT customer, MIN(order_date) first_order_date
        FROM orders
        GROUP BY customer
    ) AS o ON c.date = o.first_order_date
GROUP BY c.week_end_date

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM