Home > Blockchain >  SQL BigQuery. Check if user bought something previous month = old, if he didn't buy anything ne
SQL BigQuery. Check if user bought something previous month = old, if he didn't buy anything ne

Time:12-28

What we have:

 user_id month
    ---- 2021-08  
    1414 2021-09  
    1414 2021-10 
    1414 2021-11
    ---- 2021-12

What we need:

 user_id month
    ---- 2021-08
    1414 2021-09 new user
    1414 2021-10 old
    1414 2021-11 churn
    ---- 2021-12

in the end, I'll aggregate all of the users with COUNT(new_user) and GROUP BY status...

However, I have a problem with this stage where I need to assign correct values to users within certain months

CodePudding user response:

Something like this might work.

The first test CTE term is just to provide the test table data.

WITH test (user_id, month) AS (
    SELECT 1414, '2021-09' UNION
    SELECT 1414, '2021-10' UNION
    SELECT 1414, '2021-11' UNION
    SELECT null, '2021-08' UNION
    SELECT null, '2021-12'
     )
   , xrows AS (
    SELECT *
         , LAG(month)  OVER (PARTITION BY user_id ORDER BY month) AS lastval
         , LEAD(month) OVER (PARTITION BY user_id ORDER BY month) AS nextval
      FROM test
     )
SELECT user_id, month
     , CASE WHEN user_id IS NOT NULL THEN
            CASE WHEN nextval IS NULL THEN 'churn'
                 WHEN lastval IS NULL THEN 'new user'
                 ELSE 'old'
             END
        END AS status
  FROM xrows
 ORDER BY month
;

-- or

WITH test (user_id, month) AS (
    SELECT 1414, '2021-09' UNION
    SELECT 1414, '2021-10' UNION
    SELECT 1414, '2021-11' UNION
    SELECT null, '2021-08' UNION
    SELECT null, '2021-12'
     )
   , xrows AS (
    SELECT *
         , LAG(month)  OVER w AS lastval
         , LEAD(month) OVER w AS nextval
      FROM test
    WINDOW w AS (PARTITION BY user_id ORDER BY month)
     )
SELECT user_id, month
     , CASE WHEN user_id IS NOT NULL THEN
            CASE WHEN nextval IS NULL THEN 'churn'
                 WHEN lastval IS NULL THEN 'new user'
                 ELSE 'old'
             END
        END AS status
  FROM xrows
 ORDER BY month
;

Result:

user_id month status
2021-08
1414 2021-09 new user
1414 2021-10 old
1414 2021-11 churn
2021-12
  • Related