Advanced Window Functions

Back

Loading concept...

Advanced Window Functions: Time Travel with Your Data! ๐Ÿš€

Imagine youโ€™re watching a parade from your bedroom window. You can see whoโ€™s passing by right now, but what if you could also peek at who just passed or whoโ€™s about to come? Thatโ€™s exactly what advanced window functions let you do with your data!


The Magic Window Analogy ๐ŸชŸ

Think of your database table as a long parade of numbers marching past your window. Regular SQL only shows you whoโ€™s at your window RIGHT NOW. But with window functions, you get magical binoculars that let you:

  • ๐Ÿ‘€ Look BACK at who just passed (LAG)
  • ๐Ÿ‘€ Look FORWARD at whoโ€™s coming next (LEAD)
  • ๐Ÿ“ Set BOUNDARIES for how far you can see (Window Frame)
  • โž• Keep a RUNNING SCORE of everything (Running Totals)
  • ๐Ÿ“Š Get SUMMARIES of what you see (Aggregate Windows)

1. LAG Function: Peeking at the Past ๐Ÿ‘ˆ

What is LAG?

LAG is like having eyes in the back of your head. It lets you see the value from a previous row while staying on your current row.

Simple Example: Yesterdayโ€™s Temperature

Imagine youโ€™re tracking daily temperatures:

SELECT
  day_name,
  temperature,
  LAG(temperature, 1)
    OVER (ORDER BY day_date)
    AS yesterday_temp
FROM weather;

Result:

day_name temperature yesterday_temp
Monday 72 NULL
Tuesday 75 72
Wednesday 68 75

How LAG Works

LAG(column, offset, default)
    โ”‚        โ”‚       โ”‚
    โ”‚        โ”‚       โ””โ”€โ”€ What to show if no previous row (optional)
    โ”‚        โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ How many rows back to look (default: 1)
    โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ Which column to peek at

Real-Life Use: Price Changes

SELECT
  product_name,
  price,
  LAG(price) OVER (
    PARTITION BY product_name
    ORDER BY change_date
  ) AS old_price,
  price - LAG(price) OVER (
    PARTITION BY product_name
    ORDER BY change_date
  ) AS price_change
FROM prices;

๐ŸŽฏ Key Insight: LAG looks BACKWARDS. Think โ€œLAG = Look At past Guyโ€


2. LEAD Function: Seeing the Future ๐Ÿ‘‰

What is LEAD?

LEAD is LAGโ€™s twin sister, but she looks forward instead of backward. She tells you whatโ€™s coming NEXT!

Simple Example: Tomorrowโ€™s Weather

SELECT
  day_name,
  temperature,
  LEAD(temperature, 1)
    OVER (ORDER BY day_date)
    AS tomorrow_temp
FROM weather;

Result:

day_name temperature tomorrow_temp
Monday 72 75
Tuesday 75 68
Wednesday 68 NULL

The LEAD Pattern

LEAD(column, offset, default)
    โ”‚        โ”‚       โ”‚
    โ”‚        โ”‚       โ””โ”€โ”€ What to show if no future row
    โ”‚        โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ How many rows ahead to look
    โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ Which column to peek at

Real-Life Use: Appointment Gaps

SELECT
  appointment_time,
  patient_name,
  LEAD(appointment_time) OVER (
    ORDER BY appointment_time
  ) AS next_appointment,
  TIMESTAMPDIFF(
    MINUTE,
    appointment_time,
    LEAD(appointment_time) OVER (
      ORDER BY appointment_time
    )
  ) AS gap_minutes
FROM appointments;

๐ŸŽฏ Key Insight: LEAD looks FORWARD. Think โ€œLEAD = Look Eager to Ahead Dataโ€


3. Window Frame Clauses: Setting Your View ๐Ÿ“

What is a Window Frame?

Remember our parade analogy? A window frame decides exactly how much of the parade you can see through your magic window!

The Building Blocks

OVER (
  PARTITION BY category    -- Which parade?
  ORDER BY date           -- Which direction?
  ROWS BETWEEN ... AND ... -- How wide is window?
)

Frame Types: ROWS vs RANGE

ROWS  = Count by position (1st, 2nd, 3rd...)
RANGE = Count by value (same values = same group)

Frame Boundaries Explained

UNBOUNDED PRECEDING  โ† From the very beginning
N PRECEDING         โ† From N rows back
CURRENT ROW         โ† Right here
N FOLLOWING         โ† To N rows ahead
UNBOUNDED FOLLOWING โ† To the very end

Visual: Frame Examples

Data: [10] [20] [30] [40] [50]
            โ–ฒ (Current Row)

ROWS BETWEEN 1 PRECEDING AND CURRENT ROW:
      [20] [30]
      โ””โ”€โ”€โ”ฌโ”€โ”€โ”˜
       Window

ROWS BETWEEN 1 PRECEDING AND 1 FOLLOWING:
      [20] [30] [40]
      โ””โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”˜
         Window

ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW:
[10] [20] [30]
โ””โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”˜
   Window (all from start to here)

Practical Example: 3-Day Moving Average

SELECT
  sale_date,
  revenue,
  AVG(revenue) OVER (
    ORDER BY sale_date
    ROWS BETWEEN 2 PRECEDING
             AND CURRENT ROW
  ) AS three_day_avg
FROM sales;

4. Running Totals and Averages: The Scoreboard ๐Ÿ“Š

What are Running Totals?

Imagine keeping score in a basketball game. After each basket, you ADD to the total. You donโ€™t start overโ€”you keep a running score!

The Classic Running Total

SELECT
  order_date,
  order_amount,
  SUM(order_amount) OVER (
    ORDER BY order_date
    ROWS BETWEEN UNBOUNDED PRECEDING
             AND CURRENT ROW
  ) AS running_total
FROM orders;

Result:

order_date order_amount running_total
Jan 1 100 100
Jan 2 50 150
Jan 3 75 225

Running Average: The Moving Lens

SELECT
  test_date,
  score,
  AVG(score) OVER (
    ORDER BY test_date
    ROWS BETWEEN UNBOUNDED PRECEDING
             AND CURRENT ROW
  ) AS running_avg
FROM test_scores;

Grouped Running Totals

Want separate running totals per category? Use PARTITION BY:

SELECT
  category,
  sale_date,
  amount,
  SUM(amount) OVER (
    PARTITION BY category
    ORDER BY sale_date
    ROWS UNBOUNDED PRECEDING
  ) AS category_running_total
FROM sales;
graph TD A["Each Row"] --> B{PARTITION BY?} B -->|Yes| C["Separate Running Total<br>per Group"] B -->|No| D["One Running Total<br>for All"] C --> E["ORDER BY determines<br>accumulation order"] D --> E

5. Aggregate Window Functions: The Birdโ€™s Eye View ๐Ÿฆ…

What Makes Them Special?

Regular aggregates (SUM, AVG, COUNT) collapse many rows into one. Window aggregates give you the summary while keeping every row!

Compare: Regular vs Window

Regular Aggregate:

SELECT category, SUM(price)
FROM products
GROUP BY category;
-- Returns ONE row per category

Window Aggregate:

SELECT
  product_name,
  category,
  price,
  SUM(price) OVER (
    PARTITION BY category
  ) AS category_total
FROM products;
-- Returns EVERY row, plus the total!

The Power Trio: SUM, AVG, COUNT as Windows

SELECT
  employee_name,
  department,
  salary,
  -- Total salary in department
  SUM(salary) OVER (
    PARTITION BY department
  ) AS dept_total,
  -- Average salary in department
  AVG(salary) OVER (
    PARTITION BY department
  ) AS dept_avg,
  -- How many in department
  COUNT(*) OVER (
    PARTITION BY department
  ) AS dept_count,
  -- Your salary as % of department
  ROUND(100.0 * salary / SUM(salary)
    OVER (PARTITION BY department), 1
  ) AS pct_of_dept
FROM employees;

MIN and MAX Windows

SELECT
  product_name,
  price,
  MIN(price) OVER () AS cheapest,
  MAX(price) OVER () AS priciest,
  price - MIN(price) OVER ()
    AS above_minimum
FROM products;

Putting It All Together: A Complete Example ๐ŸŽช

Letโ€™s analyze a storeโ€™s daily sales with ALL our tools:

SELECT
  sale_date,
  daily_revenue,

  -- LAG: Yesterday's revenue
  LAG(daily_revenue) OVER w
    AS yesterday,

  -- LEAD: Tomorrow's revenue
  LEAD(daily_revenue) OVER w
    AS tomorrow,

  -- Running Total
  SUM(daily_revenue) OVER (
    ORDER BY sale_date
    ROWS UNBOUNDED PRECEDING
  ) AS running_total,

  -- 3-Day Moving Average
  AVG(daily_revenue) OVER (
    ORDER BY sale_date
    ROWS BETWEEN 2 PRECEDING
             AND CURRENT ROW
  ) AS three_day_avg,

  -- Comparison to overall average
  daily_revenue - AVG(daily_revenue)
    OVER () AS vs_overall_avg

FROM daily_sales
WINDOW w AS (ORDER BY sale_date);

Quick Reference: The Cheat Codes ๐ŸŽฎ

Function What It Does Memory Trick
LAG(col, n) Look n rows BACK Look At past Guy
LEAD(col, n) Look n rows AHEAD Lead the way forward
ROWS BETWEEN Set exact boundaries Like setting fence posts
UNBOUNDED PRECEDING From the very start โ€œSince the beginning of timeโ€
Running SUM Accumulating total Basketball scoreboard
Window AVG Average without collapsing Birdโ€™s eye view

You Did It! ๐ŸŽ‰

Youโ€™ve just learned the time-travel powers of SQL! Now you can:

  • โœ… Peek at previous values with LAG
  • โœ… See future values with LEAD
  • โœ… Control your view with Window Frames
  • โœ… Keep running scores with Running Totals
  • โœ… Get summaries while keeping details with Aggregate Windows

These arenโ€™t just fancy tricksโ€”theyโ€™re essential tools for real data analysis. Stock analysts use them for moving averages. Business analysts use them for trend analysis. And now, YOU can use them too!

๐Ÿ’ก Final Tip: Practice with small datasets first. Once you see the pattern, these functions become second nature!

Loading story...

Story - Premium Content

Please sign in to view this story and start learning.

Upgrade to Premium to unlock full access to all stories.

Stay Tuned!

Story is coming soon.

Story Preview

Story - Premium Content

Please sign in to view this concept and start learning.

Upgrade to Premium to unlock full access to all content.