|
| 1 | +-- window function to calculate a rolling average. For simplicity, let's use a 7-day rolling average. |
| 2 | + |
| 3 | +-- DAU YoY Growth Rate |
| 4 | + |
| 5 | +/* |
| 6 | +CREATE TABLE user_activity ( |
| 7 | + user_id INT, |
| 8 | + activity_date DATE |
| 9 | +); |
| 10 | +
|
| 11 | +-- Sample data for January 2024 |
| 12 | +INSERT INTO user_activity (user_id, activity_date) VALUES |
| 13 | +(1, '2024-01-01'), (2, '2024-01-01'), (3, '2024-01-01'), |
| 14 | +(1, '2024-01-02'), (2, '2024-01-02'), (4, '2024-01-02'), |
| 15 | +(1, '2024-01-03'), (3, '2024-01-03'), (4, '2024-01-03'), |
| 16 | +(2, '2024-01-04'), (3, '2024-01-04'), (5, '2024-01-04'), |
| 17 | +(1, '2024-01-05'), (2, '2024-01-05'), (5, '2024-01-05'), |
| 18 | +(3, '2024-01-06'), (4, '2024-01-06'), (5, '2024-01-06'), |
| 19 | +(1, '2024-01-07'), (2, '2024-01-07'), (3, '2024-01-07'); |
| 20 | +
|
| 21 | +-- Sample data for January 2023 |
| 22 | +INSERT INTO user_activity (user_id, activity_date) VALUES |
| 23 | +(1, '2023-01-01'), (2, '2023-01-01'), |
| 24 | +(1, '2023-01-02'), (3, '2023-01-02'), |
| 25 | +(2, '2023-01-03'), (4, '2023-01-03'), |
| 26 | +(1, '2023-01-04'), (3, '2023-01-04'), |
| 27 | +(2, '2023-01-05'), (4, '2023-01-05'), |
| 28 | +(1, '2023-01-06'), (3, '2023-01-06'), |
| 29 | +(2, '2023-01-07'), (4, '2023-01-07'); |
| 30 | +
|
| 31 | +*/ |
| 32 | + |
| 33 | + |
| 34 | +WITH daily_dau AS ( |
| 35 | + SELECT |
| 36 | + activity_date, |
| 37 | + COUNT(DISTINCT user_id) AS daily_active_users |
| 38 | + FROM |
| 39 | + user_activity |
| 40 | + GROUP BY |
| 41 | + activity_date |
| 42 | +), |
| 43 | +yoy_growth AS ( |
| 44 | + SELECT |
| 45 | + current_year.activity_date, |
| 46 | + current_year.daily_active_users, |
| 47 | + previous_year.daily_active_users AS previous_year_daily_active_users, |
| 48 | + (current_year.daily_active_users::FLOAT / previous_year.daily_active_users - 1) * 100 AS yoy_growth_rate |
| 49 | + FROM |
| 50 | + daily_dau current_year |
| 51 | + LEFT JOIN |
| 52 | + daily_dau previous_year |
| 53 | + ON |
| 54 | + current_year.activity_date = previous_year.activity_date + INTERVAL '1 year' |
| 55 | +) |
| 56 | +SELECT |
| 57 | + activity_date, |
| 58 | + daily_active_users, |
| 59 | + yoy_growth_rate, |
| 60 | + AVG(yoy_growth_rate) OVER ( |
| 61 | + ORDER BY activity_date |
| 62 | + ROWS BETWEEN 6 PRECEDING AND CURRENT ROW |
| 63 | + ) AS rolling_avg_yoy_growth_rate |
| 64 | +FROM |
| 65 | + yoy_growth |
| 66 | +ORDER BY |
| 67 | + activity_date; |
| 68 | + |
| 69 | +-- MAU YoY Growth Rate |
| 70 | + |
| 71 | +with mau as( |
| 72 | + select |
| 73 | + date_trunc('month', activity_date) activity_date, |
| 74 | + count(DISTINCT user_id) cn |
| 75 | + from |
| 76 | + user_activity |
| 77 | + group by |
| 78 | + date_trunc('month', activity_date) |
| 79 | + order by 1 |
| 80 | +), |
| 81 | +mau_yoy_growth as( |
| 82 | + select |
| 83 | + a.cn mau, a.activity_date, |
| 84 | + round(((a.cn - b.cn) * 100.0 / b.cn), 2) mau_yoy |
| 85 | + from |
| 86 | + mau a join mau b on a.activity_date = b.activity_date + interval '1 year' |
| 87 | +) |
| 88 | +select |
| 89 | + activity_date, mau, mau_yoy, |
| 90 | + round(avg(mau_yoy) over(order by activity_date ROWS BETWEEN 6 PRECEDING AND CURRENT ROW), 2) r_yoy |
| 91 | +from |
| 92 | + mau_yoy_growth |
| 93 | + |
| 94 | + |
| 95 | + |
| 96 | + |
| 97 | +/* |
| 98 | +
|
| 99 | +CREATE TABLE revenue ( |
| 100 | + transaction_date DATE, |
| 101 | + total_revenue NUMERIC |
| 102 | +); |
| 103 | +
|
| 104 | +-- Sample data for 2023 and 2024 |
| 105 | +INSERT INTO revenue (transaction_date, total_revenue) VALUES |
| 106 | +('2023-01-01', 1000), ('2023-01-02', 1100), ('2023-01-03', 1050), |
| 107 | +('2023-01-04', 1200), ('2023-01-05', 1250), ('2023-01-06', 1300), |
| 108 | +('2023-01-07', 1400), ('2023-02-01', 1500), ('2023-02-02', 1600), |
| 109 | +('2023-02-03', 1700), ('2023-02-04', 1800), ('2023-02-05', 1900), |
| 110 | +('2024-01-01', 2000), ('2024-01-02', 2200), ('2024-01-03', 2100), |
| 111 | +('2024-01-04', 2400), ('2024-01-05', 2500), ('2024-01-06', 2600), |
| 112 | +('2024-01-07', 2800), ('2024-02-01', 3000), ('2024-02-02', 3200), |
| 113 | +('2024-02-03', 3400), ('2024-02-04', 3600), ('2024-02-05', 3800); |
| 114 | +*/ |
| 115 | + |
| 116 | +with dau as (select distinct transaction_date, sum(total_revenue) sm from revenue group by transaction_date order by transaction_date), |
| 117 | +dau_yoy_revenue as ( |
| 118 | + select a.transaction_date, ((a.sm - b.sm) * 100.0) / b.sm from dau a join dau b on a.transaction_date=b.transaction_date + interval '1 year' |
| 119 | +) |
| 120 | +select * from dau_yoy_revenue |
| 121 | + |
0 commit comments