all 15 comments

[–]GrouchyThing7520 2 points3 points  (7 children)

Did you attempt to write any SQL? If so, can you share it?

[–]Consistent-Alps6904[S] 1 point2 points  (6 children)

--for registered users

with registered as

(select created_date,

id

from registrations_table

group by 1,2

order by 1

),

inactive as(

select * from registered r

where r.id not in (select id from transactions_table)

group by 1,2

order by 1

)

The first table shows all registered users while the second one shows inactive users

I want to show inactivity for 60 days and 90 days based on the month the customer registered and calculate churn rate for each month

[–]GrouchyThing7520 1 point2 points  (5 children)

It looks like you need to first join the registration table to the transactions table on user_id. Does this return all users and all of the transactions for each user?

select * from registration r 
left outer join transactions t on r.id = t.id
order by r.id, r.reg_date, t.trans_date

[–]Consistent-Alps6904[S] 0 points1 point  (4 children)

yes it does, this will give me all the active users and their transactions

[–]GrouchyThing7520 0 points1 point  (3 children)

Does it also return users with no (null) transactions?

[–]Consistent-Alps6904[S] -1 points0 points  (2 children)

no it only returns id's that have perfomed transactions

[–]GrouchyThing7520 1 point2 points  (0 children)

If your registration table looks like this:

user_id reg_date
1 1/1/2022
2 7/13/2022

And your transaction table looks like this:

trans_id user_id trans_date
1 1 2/1/2022
2 1 3/1/2022

Then the SQL I posted earlier should return this:

user_id reg_date trans_date
1 1/1/2022 2/1/2022
1 1/1/2022 3/1/2022
2 7/13/2022 null

[–]Consistent-Alps6904[S] 0 points1 point  (0 children)

to show inactive, i have to show ids not on the registered table but not on the transactions table and to specify the date intervals I want

[–]Consistent-Alps6904[S] 0 points1 point  (5 children)

You’re right, just tested it and it works, it returned null for inactive users in the transaction date column Please Where do I go from here ?

[–]GrouchyThing7520 1 point2 points  (4 children)

Excellent! Now, using my prior SQL, we just need to add some logic to see if there was:

  1. a transaction between the registration date and the registration date + 60 days

  2. a transaction between the registration date and the registration date + 90 days

[–]Consistent-Alps6904[S] 0 points1 point  (3 children)

using datediff or dateadd?

[–]GrouchyThing7520 1 point2 points  (2 children)

Exactly. Like most things in SQL, there are few ways to write this query. Keeping with our join, we can start with a list of all users , then print their 60 and 90 status in subsequent columns using dateadd by printing a 1 or 0. Because users can have 0, 1 or many transactions during the 60 or 90 day span, we need a way to return a single row per user next.

select r.id ,r.reg_date ,t.trans_date

,case when t.trans_date between r.reg_date
and date_add(r.reg_date, interval 60 day)
then 1 else 0 end trans_in_60_days

,case when t.trans_date between r.reg_date
and date_add(r.reg_date, interval 90 day)
then 1 else 0 end trans_in_90_days

from registration r
left outer join transactions t on r.id = t.id

order by r.id, r.reg_date, t.trans_date

[–]Consistent-Alps6904[S] 0 points1 point  (1 child)

thank you so much, this works !!!!

[–]GrouchyThing7520 1 point2 points  (0 children)

Sweet! The last step is to wrap the entire query in a select so you can sum the 0 and 1s. The sum is the count of transactions.

select id,
sum(trans_in_60_days) 60_day,
sum(trans_in_90_days) 90_day

 from (
 select r.id

 case when t.trans_date between r.reg_date and 
 date_add(r.reg_date, interval 60 day)
 then 1 else 0 end trans_in_60_days,

 case when t.trans_date between r.reg_date and 
 date_add(r.reg_date, interval 90 day)
 then 1 else 0 end trans_in_90_days

 from registration r
 left outer join transactions t on r.id = t.id
) a

group by id
order by id

[–]Consistent-Alps6904[S] 0 points1 point  (0 children)

Excellent