2017-12-05 5 views
0

Ich mache eine Kohortenanalyse und kann die Gruppe der Benutzer untersuchen lassen, dann sehen, ob sie in den folgenden Monaten getätigt haben. Aber ich will es so:Postgres - Kohortenanalyse über Monate sequenziell, nicht wenn in irgendeinem späteren Monat existiert

Von dieser Gruppe im Dezember, die in Jan getätigt; der Jan Gruppe von Dezember, die im Februar getätigten Im Grunde genommen bin Tracking i Verfall der Kundenbasis

Was ich will, nicht mit denen, die in jedem Monat zurückkehren folgenden Dezember, die dies ist:

WITH start_sample AS (
SELECT 
    user_fk, 
    created_at AS start_sample_date 
    FROM transactions 
    WHERE created_at >= '2016-11-01' AND created_at < '2016-12-01' 
     GROUP BY user_fk, 
     start_sample_date), 

start_sample_min AS (
SELECT 
    user_fk, 
    MIN(start_sample_date) AS first_transaction 
    FROM start_sample 
     GROUP BY user_fk 
) 

SELECT 
    DATE_TRUNC('month', created_at) AS transacting_month, 
    COUNT(DISTINCT user_fk) 
    FROM transactions 
     WHERE created_at >= '2016-11-01' 
     AND t.user_fk IN(SELECT user_fk FROM start_sample_min) 
      GROUP BY transacting_month 
      ORDER BY transacting_month; 

Dann machte ich ein Abwanderungs Modell zu sehen, ob es würde bekommen, was ich brauche, aber es funktioniert nicht:

WITH monthly_users AS (
    SELECT 
     user_fk AS monthly_user_fk, 
     DATE_TRUNC('month', created_at) AS month 
     FROM transactions 
      WHERE created_at >= '2016-11-01' AND created_at < '2017-12-01' 
      GROUP BY monthly_user_fk, month 
      ORDER BY monthly_user_fk, month 
), 

lag_lead AS (
    SELECT 
    monthly_user_fk, 
    month, 
    LAG(month,1) OVER (PARTITION BY monthly_user_fk ORDER BY month) AS lag, 
    LEAD(month,1) OVER (PARTITION BY monthly_user_fk ORDER BY month) AS lead 
     FROM monthly_users), 

lag_lead_with_diffs AS (
    SELECT 
    monthly_user_fk, 
    month, 
    lag AS previous_month, 
    lead AS next_month, 
    EXTRACT(EPOCH FROM (month - lag)/86400)::INT AS lag_size, 
    EXTRACT(EPOCH FROM (lead - month)/86400)::INT AS lead_size 
     FROM lag_lead 
), 

calculated AS (
     SELECT 
     month, 
     CASE WHEN previous_month IS NULL THEN 'ACTIVATION' 
      WHEN lag_size <= 31 THEN 'ACTIVE' 
      WHEN lag_size > 31 THEN 'RETURN' END AS this_month_values, 
     CASE WHEN (lead_size > 31 OR lead_size IS NULL) THEN 'CHURN' ELSE NULL END AS next_month_churn, 
     COUNT(DISTINCT monthly_user_fk) AS c_d_users 
    FROM lag_lead_with_diffs 
    GROUP BY month, 2, 3 
) 

SELECT 
    month, 
    this_month_values, 
    SUM(c_d_users) AS distinct_users 
    FROM calculated 
    GROUP BY month, this_month_values 
UNION 
SELECT month + INTERVAL '1 month', 
    'CHURN', 
    SUM(c_d_users) 
    FROM calculated 
    WHERE next_month_churn IS NOT NULL 
     GROUP BY month + INTERVAL '1 month', 2 
     HAVING (EXTRACT(EPOCH FROM (month + INTERVAL '1 month'))) < 1512086400 
      ORDER BY month, this_month_values; 

dies ist jedoch in der Anfangsgruppe nicht festgelegt. Die aktive Gruppe wird von Monat zu Monat gerollt.

Ich verstehe, dass die oben ist wahrscheinlich komplizierter als was ich frage, aber ich kann meinen Kopf nicht scheinen um ihn herum

Vielen Dank im Voraus zu bekommen

Antwort

1

Vielleicht ist dies, was Sie suchen für:

with Monthly_Users as (
select user_fk 
    , date_trunc('month',created_at) as month 
    , (date_part('year', created_at) - 2016) * 12 
    + date_part('month', created_at) - 11 as Months_Between 
    from transactions 
where created_at between date '2016-11-01' 
         and date '2017-12-01' 
group by user_fk, month, months_between 
), t2 as (
select Monthly_Users.* 
    , count(*) over (partition by user_fk 
          order by month rows between unbounded preceding 
                and 1 preceding) prev_rec_cnt 
    from Monthly_Users 
) 
select month 
    , count(*) 
    from t2 
where Months_Between = Prev_Rec_Cnt 
group by month 
order by month; 

In dieser Abfrage der Monthly_Users CTE ist wie bei Ihnen, aber fügt eine Berechnung der Anzahl von Months_Between das created_at Datum und Ihrem ursprünglichen Starttermins. Im zweiten allgemeinen Tabellenausdruck zähle ich die Anzahl der Vorkommen jedes Benutzers_fk vor dem aktuellen month s-Eintrag. Schließlich beschränke ich in der Ausgabeabfrage die Ergebnisse nur auf die Datensätze, bei denen der Wert Months_Between dem Wert Prev_Rec_Cnt entspricht. Alle verpassten Monate werden dazu führen, dass der Wert Prev_Rec_Cnt nicht mit dem Wert Months_Between übereinstimmt. Sie können also den Wert von user_fk von Monat zu Monat abfallen sehen.

+0

Das ist wirklich großartig, genau das, was ich brauchte. Danke – MassiveOwl

+0

Würde es Ihnen etwas ausmachen, mir mit der Zeile "Monate zwischen" Linie zu helfen? Warum machst du 2017 - 2016 * 12 -11? Ich versuche es zu konvertieren, um auch Wochen zu machen – MassiveOwl

+0

hatte nur eine Gehirnwelle, Sie müssen die Woche Nummer nehmen, die der Datensatz beginnt. Vergiss es, danke nochmal. Wenn jemand interessiert ist, ist es, (DATE_PART ('Jahr', erstellt_at) - 2016) * 52 + DATE_PART ('Woche', erstellt_at) - 45 AS Wochen zwischen – MassiveOwl

Verwandte Themen