Offset Functions (LAG/LEAD): Mistakes
Module: Window Functions
Not Providing Default Values - Causes NULL Issues
-- Missing default value causes NULL in first/last rows
SELECT date, revenue,
LAG(revenue) OVER (ORDER BY date) as prev_revenue,
revenue - LAG(revenue) OVER (ORDER BY date) as growth
FROM monthly_sales;
-- PROBLEM: First row has NULL prev_revenue, growth calculation fails
-- Provide default value to handle edge cases
SELECT date, revenue,
LAG(revenue, 1, 0) OVER (ORDER BY date) as prev_revenue,
revenue - LAG(revenue, 1, 0) OVER (ORDER BY date) as growth
FROM monthly_sales;
-- SUCCESS: First row gets 0 as prev_revenue, calculations work
LAG returns NULL when there's no previous row, LEAD returns NULL when there's no next row. This breaks arithmetic operations and makes results inconsistent. Always provide meaningful default values.
Always use the third parameter: LAG(column, offset, default_value)
High
NULL values in first/last rows break calculations and formatting
Wrong ORDER BY - Breaks Time Series Logic
-- Incorrect ordering breaks time-based analysis
SELECT month, sales,
LAG(sales, 1, 0) OVER (ORDER BY sales DESC) as prev_sales
FROM monthly_data;
-- PROBLEM: Ordered by sales amount, not chronologically
-- Correct chronological ordering for time series
SELECT month, sales,
LAG(sales, 1, 0) OVER (ORDER BY month) as prev_month_sales
FROM monthly_data;
-- SUCCESS: Ordered by time, LAG gets actual previous month
LAG and LEAD are position-based, not value-based. If you ORDER BY sales amount, LAG gets the row with the next-highest sales, not the previous time period. Always ORDER BY your time/sequence column.
For time series: ORDER BY date/time columns, not by the values you're analyzing
Critical
Ordering by wrong column makes LAG/LEAD meaningless for time analysis
Forgetting PARTITION BY for Grouped Analysis
-- Missing PARTITION BY mixes different groups
SELECT product_id, month, sales,
LAG(sales, 1, 0) OVER (ORDER BY month) as prev_sales
FROM product_monthly_sales;
-- PROBLEM: Gets previous month from different product!
-- PARTITION BY keeps comparisons within same group
SELECT product_id, month, sales,