Portfolio project · SQL, pandas · Intermediate · 12 to 16 hours

Customer cohort retention analysis

Do first-time buyers come back, and is that getting better or worse? You group customers by the month of their first order and follow each group over time. Doing it in SQL and again in pandas, with matching numbers, shows two skills and the habit of checking your own work.

The business question

What share of first-time customers order again within 90 days, by month of first order, and is it improving?

Turned into a SMART goal, so you know when you are done and a reviewer can see you scoped it like an analyst:

Specific
90-day repeat rate for each monthly cohort of first-time customers, plus a month-by-month retention grid.
Measurable
One rate per cohort with the cohort size next to it, and the same numbers from SQL and from pandas.
Achievable
One dataset, a SQL engine you can run locally (DuckDB, SQLite or PostgreSQL) and one notebook.
Relevant
Tells marketing whether to spend on new customers or on bringing first-time buyers back.
Time-bound
Cohorts from the dataset’s first full year; cohorts with less than 90 days of data left are excluded. Done in three weeks.

Datasets

Public data, free to download. Pick one, read its license on the source page, and link that page in your README rather than uploading the files.

UCI Machine Learning Repository

Online Retail II

Two years of invoices with a customer ID and a timestamp on each line, so you can follow customers month by month. A common choice for cohort analysis.

Drop lines with no customer ID and treat C invoices as cancellations before you look for first orders.

Kaggle

Brazilian E-Commerce Public Dataset by Olist

A harder version: most customers order only once, so the story is how small the repeat base is and what sets the returning customers apart.

Use customer_unique_id. customer_id is created per order, so with it every customer looks like a one-time buyer.

Google BigQuery public datasets

theLook eCommerce

A synthetic clothing store with users, orders and order items, at bigquery-public-data.thelook_ecommerce. Query it with SQL in the free BigQuery sandbox.

The data is generated, so say so in the write-up and keep the findings about method rather than about a real business.

Step by step

Each step links to AnalystQuest levels that teach the skill on the Harbor & Pine store data, so you can practise it before you do it on the real dataset.

  1. Define customer, cohort and “came back”

    Write the rules before any query. A customer is one person, not one account or one order. Their cohort is the month of their first completed order. They came back if a second completed order follows within 90 days.

    Decide what to do with young cohorts: customers who first bought in the last 90 days of the data have not had the full window yet. Leave those cohorts out or mark them as incomplete. This is right-censoring, and interviewers ask about it.

  2. Clean to one row per customer

    Remove cancellations and rows without a customer, merge duplicate customers, and check the date range. Count customers and orders before and after, and keep those counts for the README.

  3. Build the cohorts in SQL

    Find each customer’s first order with MIN or ROW_NUMBER, give every later order a month offset from it, then count distinct customers per cohort and offset and divide by the cohort size. Save the queries as .sql files in the repo, not only in a notebook.

  4. Rebuild in pandas and draw the grid

    Repeat the calculation with groupby and pivot_table and confirm it matches SQL cohort by cohort. Then draw the retention grid as a heatmap: cohorts down the side, months since first order across, the rate in each cell and the cohort size in the label.

    Add one line chart of the 90-day repeat rate per cohort. That is the chart that answers the question; the grid is the evidence.

  5. Write it up

    Lead with the rate and the trend, then the cohorts that stand out and a reason you can check (season, first product category, channel). Say clearly what the data cannot tell you, such as whether a discount caused a return.

What to show

The same project, packaged three ways. Numbers in brackets are placeholders: replace them with your own results.

GitHub

README, in this order

  1. Question and SMART goal
  2. Retention grid image
  3. Definitions: customer, cohort, came back, window
  4. Data: source link, license, rows before and after cleaning
  5. Findings and recommendation
  6. How to run the SQL and the notebook

Files

  • sql/01_clean.sql: cleaning and the one-row-per-customer table
  • sql/02_cohorts.sql: first orders, month offsets, the grid
  • notebooks/retention.ipynb: the pandas rebuild, the match check and the charts
  • images/retention_grid.png: the heatmap for the README

LinkedIn

Post outline

  1. Open with the rate: "[X]% of first-time buyers came back within 90 days."
  2. One line on why it matters: repeat customers are cheaper to win than new ones.
  3. One line on method: monthly cohorts in SQL, checked against pandas.
  4. The cohort that surprised you and your best explanation.
  5. The grid image and the repo link; ask how others treat incomplete cohorts.

CV

Two bullets

  • Built monthly retention cohorts for [5,900] customers in SQL and pandas, with results matching row for row, showing [X]% of first-time buyers reorder within 90 days.
  • Found that customers acquired in [Nov–Dec] reorder at [half] the rate of [spring] cohorts; recommended a [60-day] win-back email to [marketing].

Start with a verb, include a number, and name the tool. Every number must be one you can explain in an interview.

Write-up template

Copy it into your README or a document and replace each bracket. Keep the executive summary to what a busy manager would read.

# [Project title]: customer cohort retention

## Executive summary
[The 90-day repeat rate, its trend, and the one action you recommend.]

## Objective
What share of first-time customers order again within 90 days, by month of first order, and is it improving? Audience: [marketing lead].

## Data and limits
Source: [dataset, link, license]. Period: [dates].
Customers after cleaning: [n]. Removed: [n] cancellations, [n] rows without a customer.
Cohorts after [month] excluded: fewer than 90 days of data (right-censoring).
Limits: [no marketing data, so returns cannot be tied to campaigns].

## Method
Customer = [..]. Cohort = month of first completed order. Came back = second completed order within 90 days. Built in SQL ([engine]); rebuilt in pandas and matched cohort by cohort.

## Findings
1. [Overall rate and trend, with numbers.]
2. [Strongest and weakest cohorts, with sizes.]
3. [What the strong cohorts have in common.]

## Recommendations
[One or two actions and how you would measure them.]

## Next steps
[e.g. revenue retention, not only customer retention; a test of the win-back offer.]

Common mistakes

  • Counting the first order as a return, so every customer looks retained.
  • Using an order-level ID as the customer ID.
  • Including cohorts that have not had the full window, which makes recent months look worse.
  • Counting canceled orders as activity.
  • Showing rates without cohort sizes. A 40% rate on 12 customers is noise.
  • One overall average instead of the per-cohort trend the question asked for.

How long it takes

About 12 to 16 hours for a first version, spread over one to three weeks of evenings.

Define
1 hour
Clean
3 hours
SQL cohorts
3 to 4 hours
pandas rebuild and charts
3 to 5 hours
Write up
2 to 3 hours

Other portfolio projects

Excel, Power BI · 10 to 13 hours

E-commerce sales dashboard

One page a head of sales can read in a minute: revenue, orders, average order value and where they moved.

Python, Statistics · 8 to 12 hours

A/B test analysis and write-up

Check the split, estimate the lift with a confidence interval, and write a decision a product manager can act on.

Pick what may run on this site. You can change this any time from "Cookie settings" at the bottom of every page.