Module P-1·20 min read

CTEs, window functions, upserts, subqueries, UNION — the SQL that separates proficient engineers from beginners.

P-1 — Advanced SQL: The Patterns You Will Use Every Week

Who this module is for: You completed Phase 1 and can write fundamental SQL. Phase 2 assumes you are building real applications and need the SQL patterns that separate engineers who can write queries from engineers who can write good queries. This module covers the constructs that appear in almost every production PostgreSQL codebase.


Common Table Expressions (CTEs) — WITH Clauses

A CTE creates a named, temporary result set within a query. It makes complex queries readable by breaking them into named steps.

sql

Chaining Multiple CTEs

sql

CTEs execute once and are referenced by name — they are not re-executed for each reference. This is important for performance.

Recursive CTEs — Traversing Hierarchies

Recursive CTEs can traverse tree structures (org charts, categories with subcategories, file systems):

sql

Window Functions — Computation Without Collapsing Rows

Aggregate functions collapse many rows into one. Window functions compute across a set of rows but keep every row in the output.

sql

The OVER() Clause

OVER() defines the "window" — the set of rows each calculation sees:

sql

Essential Window Functions

Ranking:

sql
DifferenceWhen there is a tie
ROW_NUMBER()Assigns unique numbers (arbitrary tie-breaking)
RANK()Tied rows get same rank; next rank skips numbers (1,1,3)
DENSE_RANK()Tied rows get same rank; next rank does not skip (1,1,2)

Access previous/next rows:

sql

Running totals:

sql

Percentile:

sql

Subqueries

A subquery is a query nested inside another query.

Scalar subquery (returns one value)

sql

IN subquery (returns a list)

sql

EXISTS — Efficient Existence Check

EXISTS stops as soon as it finds the first match — more efficient than IN for large tables:

sql

Correlated subquery (references outer query)

sql

INSERT ... ON CONFLICT — Upsert

Upsert inserts a row if it does not exist, updates it if it does. Essential for idempotent writes.

sql
sql
sql

RETURNING with DML — Get Data Back Without a Second Query

RETURNING retrieves data from modified rows in the same statement:

sql

UNION, INTERSECT, EXCEPT

Combine result sets from multiple SELECT statements:

sql

CASE Expressions — Inline Conditionals

sql

Practical Exercise: Task Dashboard Queries

Using the task manager schema from F-7:

sql

Summary

FeatureWhen to Use
CTE (WITH)Break complex queries into readable named steps
Recursive CTETraverse hierarchical data (org charts, categories)
ROW_NUMBER()Unique sequential position
RANK() / DENSE_RANK()Position with tied rows
LAG() / LEAD()Access previous/next row values
Running SUM() OVERCumulative totals
Scalar subquerySingle-value comparison (price > (SELECT AVG...))
EXISTSEfficient check for row existence
ON CONFLICT DO UPDATEUpsert — insert or update atomically
ON CONFLICT DO NOTHINGInsert if not exists, ignore if duplicate
RETURNINGGet modified row data back without a second query
FILTER (WHERE ...)Conditional aggregation without subqueries
CASE WHENInline conditional logic in SELECT

Module P-2 covers indexing from a practitioner's perspective — not the internals (that is Phase 3), but when to add an index, when not to, and how to read EXPLAIN output to measure the difference.

Next: P-2 — Indexes — When and How to Add Them →


Knowledge Check

A Senior Software Engineer is optimizing a complex report that uses a Common Table Expression (CTE) named sales_summary multiple times within the final SELECT statement. They are concerned about potential performance bottlenecks due to repeated execution of the sales_summary logic. Based on PostgreSQL's behavior with CTEs, what is the most accurate understanding of how sales_summary will be executed?


A database architect is designing a query to identify all customers who have placed at least one order with a total value exceeding $500. The customers table is very large, and the orders table contains millions of records. Which SQL construct is generally the most performant and idiomatic for this specific existence check in PostgreSQL, and why?


A developer is tasked with calculating the average price of products within each category and displaying this average alongside every product in that category. However, their current query is incorrectly showing the overall average price of *all* products for every row. Which of the following is the most likely cause of this issue in their window function implementation?

Test your knowledge with more question sets

Sign in to access a wider variety of questions and get notified when new practice sets are added to this module.

Sign in & Register

Discussion

0

Join the discussion

Loading comments...

© 2026 Jatin Jain Saraf (JJS). All rights reserved.