SQL AGE
Computes a human-friendly 'X years, Y months, Z days' breakdown between two dates — more readable than a raw day count for long spans.
What & Why
AGE(later, earlier) returns a calendar-aware interval in years, months, days, and time. User 102 uses the real churned_at value; active users use the fixed April 30, 2024 teaching boundary.
See How It Works
BUSINESS QUESTION
Growth wants observed account age from signup until churn, or until 2024-04-30 for active users.
| id | created_at | country | channel | plan | activated_at | churned_at |
|---|---|---|---|---|---|---|
| 101 | 2024-01-15 09:10:00+00 | US | organic | pro | 2024-01-16 14:25:00+00 | NULL |
| 102 | 2024-02-10 11:05:00+00 | CA | paid | free | NULL | 2024-03-20 10:00:00+00 |
| 103 | 2024-03-12 16:35:00+00 | GB | referral | pro | 2024-03-13 08:15:00+00 | NULL |
| 104 | 2024-04-01 13:20:00+00 | US | organic | free | 2024-04-03 12:00:00+00 | NULL |
EXAMPLE QUERY
SELECT
id AS user_id,
AGE(COALESCE(churned_at, TIMESTAMPTZ '2024-04-30 00:00:00+00'), created_at) AS account_age
FROM growth.users
ORDER BY user_id;RESULT — exact output from the displayed Queryflo rows
| user_id | account_age |
|---|---|
| 101 | 3 mons 14 days 14:50:00 |
| 102 | 1 mon 9 days 22:55:00 |
| 103 | 1 mon 17 days 07:25:00 |
| 104 | 28 days 10:40:00 |
AGE uses churn for user 102 and the fixed 2024-04-30 boundary for active users.
Now You Try
Practice this concept
Return account age for every user, ending at churned_at when present and otherwise at the fixed 2024-04-30 teaching timestamp.
Available schema
growthPrefix tables with growth.table_name.
user_idaccount_agegrowth.users| Column | Type |
|---|---|
| id | integer |
| created_at | timestamp with time zone |
| country | text |
| channel | text |
| plan | text |
| activated_at | timestamp with time zone |
| churned_at | timestamp with time zone |
| legacy_user_code | text |
query.sql
Sign up free to try it on a real business scenario