Lesson 2 of 4

Progress: 0/3 exercises solved (0%)

← Previous

Solve all exercises below to unlock the next lesson.

LAG, LEAD, and running totals

Lesson Description

Look at the row before/after; accumulate values.

Easy Project

Mini project: Turn this lesson into a real-world query artifact by writing one clean business report query and validating output quality.

These window functions look at neighboring rows or accumulate values over an ordered sequence.

LAG() — look at the previous row

LAG(col, n, default) returns the value of col from n rows before the current row:

SELECT
  first_name,
  hire_date,
  salary,
  LAG(salary) OVER (ORDER BY hire_date) AS prev_hire_salary,
  salary - LAG(salary) OVER (ORDER BY hire_date) AS salary_diff
FROM employees
ORDER BY hire_date;

LEAD() — look at the next row

LEAD(col, n, default) returns the value from n rows ahead:

SELECT
  order_date,
  id AS order_id,
  LEAD(order_date) OVER (ORDER BY order_date, id) AS next_order_date
FROM orders;

Default when there is no neighbor

The third argument sets the value when no prior/next row exists (default is NULL):

LAG(salary, 1, 0) OVER (ORDER BY hire_date)  -- returns 0 for the first row

Running total with SUM() OVER

SELECT
  order_date,
  id,
  COUNT(*) OVER (ORDER BY order_date, id) AS running_count
FROM orders
ORDER BY order_date, id;

Running total with actual amounts

SELECT
  hire_date,
  salary,
  SUM(salary) OVER (ORDER BY hire_date, id) AS cumulative_payroll
FROM employees
ORDER BY hire_date;

Tips

  • PARTITION BY resets the running total at the start of each group.
  • LAG/LEAD with PARTITION BY looks at neighbors within the partition only.
  • For period-over-period analysis: compare current row value to LAG(value, 12) for monthly year-over-year.

Learning context

This lesson is part of Window Functions. Focus on the core idea in LAG, LEAD, and running totals, then validate with deliberate practice.

What to master

  • Understand clause order and intent
  • Write deterministic result queries
  • Use clear aliases and readable structure

Common mistakes

  • Skipping ORDER BY in final outputs
  • Using joins before validating base rows
  • Not checking row counts after changes

High-level strategy

  • Start simple, then layer complexity
  • Run often and compare expected shape
  • Refactor with CTEs when logic grows

Task ladder

  1. Baseline query: get a correct first output.
  2. Add one complication: edge case, join, filter, or ranking rule.
  3. Re-run and refine until output is stable and explainable.

Transparent data checks

  • Check row count before and after each major clause.
  • Validate one manual sample row for correctness.
  • Confirm final ordering and column naming for trust.

Retention loop

  • Run the solution once.
  • Rewrite from memory with one variation.
  • Explain the logic in plain English in one sentence.

Logical reasoning for commands

WHERE

Why: Limits rows to only the business-relevant subset.

Memory cue: Filter early to reduce noise.

ORDER BY

Why: Makes output deterministic and reviewable.

Memory cue: No ORDER BY means no guaranteed row order.

AS alias

Why: Makes output columns readable for teams and reports.

Memory cue: If the name is clear, the query is easier to trust.

Concept check

Quick check: LAG, LEAD, and running totals

3 quick questions. One at a time. Instant score at the end.

Exercise 1

Running total of orders by date

Commerce Operations Intelligencehard

From the store sandbox, return one row per order with order_date, id (order_id), and a running_orders column showing the cumulative count of orders up to and including that date, ordered by order_date then id.

Run a query to see results here.
Exercise 2

Salary gap between consecutive hires

Enterprise Workforce Analyticseasy

Return first_name, last_name, hire_date, salary, and salary_diff — the difference between this employee's salary and the previous hire's salary (ordered by hire_date, then id). Use LAG.

Run a query to see results here.
Exercise 3

Next order date per order

Commerce Operations Intelligenceeasy

From the store sandbox, return id (alias order_id), order_date, and next_order_date (the date of the following order when sorted by order_date, id). Use LEAD.

Run a query to see results here.

Lesson 2 of 4

0/3 solved (0%)

← Previous

Finish this lesson to unlock next.