0

I have this query that I use to calculate returning customers (with more than one order)

SELECT COUNT(*)
  FROM (SELECT customer_id, COUNT(*) as order_count
        FROM orders
        WHERE shop_id = #{shop_id}
          AND orders.active = true
          AND orders.created_at >= '#{from}'
          AND orders.created_at < '#{to}'
        GROUP BY customer_id
        HAVING COUNT(orders) > 1
        ORDER BY order_count) src;

And if I want new customers (that have only one order) I simply change this line:

HAVING COUNT(orders) = 1

Now, how can I generate a series between 2 given dates that will give me the number of new and returning customers for each day between the dates?

Expected result:

date new returning
2022-01-01 2 3
2022-01-02 5 9

I have tried this but doesn't work at all (error syntax near from is the error I'm getting) and I'm not sure how to fix. Ideas?

    select *, return_customers
      from (select created_at, count(*) as order_count
      from orders
      where shop_id = 43
        and created_at >= '2022-07-01'
        and created_at < '2022-07-10'
      group by customer_id
      having count(orders) > 1
      order by order_count) as return_customers from generate_series(timestamp '2007-01', timestamp '2022-07-11', interval '1 day')
    as g(created_at)
    left join (
        select created_at::date,
                count(*) as order_count
                from orders
                where shop_id 43
                and created_at >= '2022-07-01'
                and created_at < '2022-07-10'
                group by customer_id
                having count(orders) > 1
                order by order_count
                group by 1) o using (created_at)) sub
order by created_at desc;

1 Answer 1

1

This is based on your initial query w/o the having clause and conditional counts with filter. order by in src is redundant too.

SELECT src.order_date as "date", 
       COUNT(*) filter (where order_count > 1) as "returning",
       COUNT(*) filter (where order_count = 1) as "new"
FROM 
(
  SELECT date_trunc('day', o.created_at)::date as order_date, 
         COUNT(*) as order_count
  FROM orders o
  WHERE o.shop_id = #{shop_id}
    AND o.active
    AND o.created_at >= '#{from}'
    AND o.created_at < '#{to}'
  GROUP BY o.customer_id, order_date
) as src
group by order_date;
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.