Sqlism
Loading…
Learning path

Become a Data Scientist with SQL

Before a model ever sees your data, SQL is what shaped it — aggregated it, cleaned it, sampled it, and turned raw rows into features. This path moves past querying into the statistical and feature-engineering patterns data scientists reach for while a notebook is still empty.

8 Modules
~5 hrs, self-paced
2 Portfolio Projects
0 of 8 modules complete

A data scientist's SQL work happens before the modeling does. This path assumes you can already write a SELECT — it's built around what comes next: summarizing a column honestly, spotting the outliers that would poison a model, engineering features with window functions, and assembling a dataset you can hand to Python (or anything else) with confidence that it's reproducible and correctly split.

  1. 1

    Descriptive Statistics & Aggregates

    30 min

    Before you engineer a single feature, you need to know what's actually in the column — its center, its spread, and how much it varies. AVG, STDDEV, and VARIANCE run inside the database, on the full table, without pulling a single row into memory first.

    SELECT
        department_id,
        AVG(salary) AS mean_salary,
        STDDEV(salary) AS salary_stddev,
        VARIANCE(salary) AS salary_variance
    FROM employees
    GROUP BY department_id;
    A high standard deviation relative to the mean is often the first signal that a column needs outlier handling before it's safe to feed a model.
  2. 2

    Percentiles, Median & Distributions

    35 min

    The mean lies about skewed data — a handful of extreme values can drag it far from where most of your data actually sits. PERCENTILE_CONT and PERCENTILE_DISC give you the median and quartiles directly, and NTILE buckets a distribution into equal groups without a single line of application code.

    SELECT
        PERCENTILE_CONT(0.5) WITHIN GROUP (ORDER BY salary) AS median_salary,
        PERCENTILE_CONT(0.25) WITHIN GROUP (ORDER BY salary) AS p25,
        PERCENTILE_CONT(0.75) WITHIN GROUP (ORDER BY salary) AS p75
    FROM employees;
    When the mean and median disagree by a lot, that gap is telling you the distribution is skewed — trust the median for a "typical" value.
  3. 3

    Window Functions for Feature Engineering

    45 min

    Where an analyst uses window functions for reporting, a data scientist uses the same functions to build features: a rolling average as a smoothed signal, a lagged value as a "previous period" input, a rank as a normalized position within a group. Same syntax, different purpose — the output column feeds a model instead of a dashboard.

    SELECT
        customer_id,
        order_date,
        revenue,
        AVG(revenue) OVER (
            PARTITION BY customer_id
            ORDER BY order_date
            ROWS BETWEEN 6 PRECEDING AND CURRENT ROW
        ) AS revenue_7day_avg,
        LAG(revenue, 1) OVER (PARTITION BY customer_id ORDER BY order_date) AS prev_revenue
    FROM orders;
    A rolling average or a lagged value computed in SQL is a feature your model can use directly — no separate feature-engineering script required.
  4. 4

    Outlier Detection & Data Quality Profiling

    35 min

    A handful of bad rows — a negative age, a duplicate order, a NULL where a number was expected — can quietly distort a model far more than they'd distort a report. The interquartile range (IQR) gives you a defensible, purely-SQL way to flag values that don't belong, before they ever reach a training set.

    WITH bounds AS (
        SELECT
            PERCENTILE_CONT(0.25) WITHIN GROUP (ORDER BY amount) AS q1,
            PERCENTILE_CONT(0.75) WITHIN GROUP (ORDER BY amount) AS q3
        FROM transactions
    )
    SELECT t.*
    FROM transactions t, bounds b
    WHERE t.amount < b.q1 - 1.5 * (b.q3 - b.q1)
       OR t.amount > b.q3 + 1.5 * (b.q3 - b.q1);
    Flagging outliers isn't the same as deleting them — decide deliberately whether a value is bad data or a real, rare event worth keeping.
  5. 5

    CTEs & Recursive Queries for Data Prep

    35 min

    Real feature-prep queries stack up: filter, join, aggregate, then aggregate again. CTEs keep that pipeline readable as named, sequential steps instead of a wall of nested subqueries. Recursive CTEs go further, walking hierarchical or graph-shaped data — an org chart, a referral network — that a single flat query can't traverse.

    WITH RECURSIVE referral_chain AS (
        SELECT id, referred_by, 1 AS depth
        FROM users
        WHERE referred_by IS NULL
    
        UNION ALL
    
        SELECT u.id, u.referred_by, rc.depth + 1
        FROM users u
        JOIN referral_chain rc ON u.referred_by = rc.id
    )
    SELECT * FROM referral_chain;
    Reach for a recursive CTE whenever a feature depends on "how many steps away" — referral depth, org-chart level, or a bill-of-materials explosion.
  6. 6

    Sampling & Reproducible Train/Test Splits

    30 min

    Pulling a full table just to prototype against it wastes time and compute. A deterministic hash-based split — the same row always lands in the same bucket — gives you a reproducible train/test split without a random seed drifting between runs, and NTILE over a partition gives you stratified sampling that respects group balance.

    SELECT
        *,
        CASE WHEN MOD(customer_id, 10) < 8 THEN 'train' ELSE 'test' END AS split
    FROM customers;
    Hashing on a stable ID (not a random function) means the split is reproducible across every pipeline run — the same row never flips sides.
  7. 7

    Feature Engineering: CASE, PIVOT & Encoding

    35 min

    CASE is how you bin a continuous value into ranges or one-hot encode a category without leaving the database. PIVOT-style aggregation turns long, categorical data into the wide, one-column-per-feature shape most model-training code expects.

    SELECT
        customer_id,
        CASE
            WHEN age < 25 THEN 'under_25'
            WHEN age BETWEEN 25 AND 40 THEN '25_to_40'
            ELSE 'over_40'
        END AS age_bucket,
        SUM(CASE WHEN category = 'electronics' THEN amount ELSE 0 END) AS electronics_spend,
        SUM(CASE WHEN category = 'apparel' THEN amount ELSE 0 END) AS apparel_spend
    FROM purchases
    GROUP BY customer_id, age_bucket;
    Binning and encoding in SQL means the feature table is already model-ready by the time it lands in a dataframe — no post-processing pass needed.
  8. 8

    Building Model-Ready Datasets: Views & Materialization

    30 min

    The last step is packaging everything above into something reusable. A view keeps a feature definition as one source of truth that always reflects live data; materializing it into a table trades that freshness for speed when a training job needs to hit the same dataset repeatedly without recomputing it.

    CREATE VIEW customer_features AS
    SELECT
        customer_id,
        AVG(order_amount) AS avg_order_value,
        COUNT(*) AS order_count,
        MAX(order_date) AS last_order_date
    FROM orders
    GROUP BY customer_id;
    A view is a live feature definition; a materialized table is a snapshot. Pick based on whether your training job needs freshness or speed.

Practice on real projects

Build something end-to-end using the statistics, feature-engineering, and data-quality patterns from this path.

Get interview-ready

Data Scientist SQL interviews lean on statistical reasoning, window functions, and feature-engineering scenarios — exactly what this path covered.

Validate what you've learned

25 questions covering everything above. Score 80% or higher to earn your Data Scientist badge on your dashboard.

Upgrade to Sqlism Pro to take the validation quiz

25 questions · pass at 80%+ to earn your Data Scientist badge on your dashboard. One-time payment, lifetime access.

Get Sqlism Pro