LAG and LEAD help you look at data from other rows in the same table. This is useful to compare values between rows easily.
LAG and LEAD for row comparison in PostgreSQL
LAG(column_name, offset, default_value) OVER (PARTITION BY partition_column ORDER BY order_column) LEAD(column_name, offset, default_value) OVER (PARTITION BY partition_column ORDER BY order_column)
LAG looks at a previous row's value.
LEAD looks at a next row's value.
Offset is how many rows back or forward to look (default is 1).
Default value is used if there is no row to look at.
SELECT sales, LAG(sales) OVER (ORDER BY date) AS prev_sales FROM sales_data;
SELECT date, price, LEAD(price, 1, 0) OVER (ORDER BY date) AS next_price FROM stock_prices;
SELECT employee, salary, LAG(salary, 2) OVER (PARTITION BY department ORDER BY employee) AS salary_two_before FROM employees;
This example creates a sales table and shows each day's sales, the previous day's sales, and the next day's sales for easy comparison.
CREATE TABLE sales_data (date DATE, sales INT); INSERT INTO sales_data VALUES ('2024-01-01', 100), ('2024-01-02', 150), ('2024-01-03', 130), ('2024-01-04', 170); SELECT date, sales, LAG(sales) OVER (ORDER BY date) AS prev_sales, LEAD(sales) OVER (ORDER BY date) AS next_sales FROM sales_data;
If there is no previous or next row, LAG or LEAD returns NULL or the default value you set.
Always use ORDER BY inside OVER() to define the row order for comparison.
You can use PARTITION BY to restart the comparison for groups, like departments or categories.
LAG and LEAD let you peek at other rows to compare values easily.
Use ORDER BY to control which rows are compared.
They help find trends, changes, or gaps in your data without complex joins.
Practice
LAG function in PostgreSQL?Solution
Step 1: Understand LAG function behavior
TheLAGfunction returns the value from a previous row based on the current row's position.Step 2: Compare with other options
LEADaccesses the next row, sorting and deleting duplicates are unrelated toLAG.Final Answer:
To access data from a previous row in the same result set -> Option DQuick Check:
LAG = previous row data access [OK]
- Confusing LAG with LEAD
- Thinking LAG sorts rows
- Assuming LAG deletes duplicates
LEAD to get the next row's salary ordered by employee_id?Solution
Step 1: Recall correct LEAD syntax
The correct syntax usesLEAD(column) OVER (ORDER BY column)to specify the column and ordering.Step 2: Check each option
LEAD(salary) OVER (ORDER BY employee_id) matches the correct syntax; others misuse parentheses or clause order.Final Answer:
LEAD(salary) OVER (ORDER BY employee_id) -> Option AQuick Check:
LEAD(column) OVER (ORDER BY column) [OK]
- Placing ORDER BY outside OVER clause
- Missing parentheses around ORDER BY
- Putting ORDER BY inside function parameters
sales with columns month and revenue, what will this query return?SELECT month, revenue, LAG(revenue) OVER (ORDER BY month) AS prev_revenue FROM sales;
Solution
Step 1: Understand LAG with ORDER BY month
TheLAG(revenue)returns the revenue from the previous month ordered bymonth.Step 2: Interpret query output
Each row shows current month revenue and previous month's revenue inprev_revenue. The first row'sprev_revenuewill be NULL.Final Answer:
Each row shows current month revenue and previous month's revenue -> Option CQuick Check:
LAG = previous row value [OK]
- Confusing LAG with LEAD
- Expecting next month's revenue instead
- Thinking query causes error
SELECT employee_id, salary, LEAD(salary) ORDER BY employee_id FROM employees;
Solution
Step 1: Check LEAD function syntax
LEAD requires an OVER() clause to specify ordering and partitioning.Step 2: Analyze query structure
The query usesLEAD(salary)withoutOVER(), causing a syntax error.Final Answer:
Missing OVER() clause for LEAD function -> Option BQuick Check:
Window functions need OVER() [OK]
- Omitting OVER() clause
- Placing ORDER BY outside OVER()
- Confusing window functions with aggregates
hire_date. Which query correctly uses LAG to achieve this?Solution
Step 1: Understand LAG usage for filtering
Window functions likeLAGcannot be used directly in WHERE clause; use subquery or CTE to compute then filter.Step 2: Analyze options
SELECT employee_id, salary FROM (SELECT employee_id, salary, LAG(salary) OVER (ORDER BY hire_date) AS prev_salary FROM employees) t WHERE salary > prev_salary; correctly uses subquery. The second option's subquery LAG lacks OVER clause (syntax error). The third uses alias in WHERE (invalid). The fourth uses HAVING without GROUP BY (invalid).Final Answer:
SELECT employee_id, salary FROM (SELECT employee_id, salary, LAG(salary) OVER (ORDER BY hire_date) AS prev_salary FROM employees) t WHERE salary > prev_salary; -> Option AQuick Check:
Subquery to filter on window functions [OK]
- Using alias in WHERE clause
- Misusing HAVING without GROUP BY
- Incorrect subquery for LAG
Ready to prove it?
Pass the test and this pattern moves unknown
