Common Table Expressions (CTE)

SQL · Extra Concepts

Theory

A Common Table Expression (CTE) is a named, temporary result set that you define at the top of a query with WITH name AS (SELECT ...), and then use in the main query as if it were a table. It exists only while that one statement runs; nothing is saved in the database.

CTEs let you break a big query into readable steps. Instead of nesting a subquery three levels deep, you write step 1 (filter high earners), give it a name, then write step 2 (count them by department) using that name. You can define several CTEs separated by commas, and later ones can refer to earlier ones, so the query reads top to bottom like a recipe. Each CTE can also be referenced more than once in the main query. CTEs are supported by PostgreSQL, SQL Server, Oracle, Snowflake, MySQL, BigQuery and SQLite. Whether the database computes a CTE once or inlines it like a subquery depends on its optimizer, so treat CTEs mainly as a readability tool.

Why we use it

Deeply nested subqueries are hard to read, debug and reuse. A CTE gives each step a meaningful name, so complex logic becomes a series of small, testable blocks.

When to use it

Use CTEs for multi-step transformations, for reusing the same intermediate result twice and for recursive queries. For a simple one-off filter a plain WHERE is enough. If many queries need the same logic, create a view instead.

How it works

  1. Query begins with WITH
  2. Define step 1: high_earners AS (SELECT ... WHERE salary > 70000)
  3. Need more steps? Yes: Add a CTE after a comma. No: Move to the main query.
  4. Main SELECT reads from the CTE names like tables
  5. CTEs disappear when the statement finishes
  6. Return the final result

Syntax

WITH cte_name AS (
  SELECT ...
)
SELECT * FROM cte_name;

Example

WITH high_earners AS (
  SELECT * FROM employees WHERE salary > 70000
)
SELECT department, COUNT(*) FROM high_earners GROUP BY department;

Key points

SQL topics

Introduction to SQL

Querying Data

Sorting Rows

Limiting Rows

Filtering Rows

Joining Multiple Tables

Grouping Rows

SET Operators

Working with Tables

Modifying Data

Views & Triggers

Conditional Expressions

SQL Subqueries

Aggregate Functions

Window Functions

String Functions

Date Functions

Math Functions

Extra Concepts

T
Tech Town
Log InSign Up Free
Home SQL Python DSA Power BI Snowflake Databricks Spark Gen AI Practice Problems Contest Blog

Master SQL from Zero to Pro

All SQL topics in one place. Click any topic in the sidebar — content opens right here without leaving the page.

{{ sectionCount }}
Sections
{{ topicCount }}
Topics
Free
Forever
Hands-on practice Practice SQL Online Solve 150 SQL interview problems in a live editor with instant checking. Start practising →
Section {{ sec.num }}

{{ sec.label }}

SQL  /  {{ current.sectionLabel }}  /  {{ current.name }}

{{ current.name }}

Theory

{{ current.def }}

Why we use it

{{ rich.why }}

When to use it

{{ rich.when }}

Diagram

{{ rich.dg.caption }}

{{ tb.title }}
{{ c.v }}
{{ rich.dg.op }}
➜
{{ rich.dg.output.title }}
{{ c.v }}
{{ nd.label }}
{{ nd.sub }}
{{ nd.label }}
{{ nd.sub }}
{{ rich.dg.left.title }}
{{ it }}
{{ rich.dg.right.title }}
{{ it }}
Flowchart — how it works
{{ nd.text }}
{{ nd.text }}
◇ {{ nd.text }}
Yes → {{ nd.yes }}
No → {{ nd.no }}
Syntax
{{ current.syntax }}
Example
{{ current.example }}
▶ Try It Live — runs against a real sample database
{{ liveError }}
{{ col }}
{{ cell }}
Key Points — click to check off as you learn
  • {{ pt.mark }} {{ pt.text }}

Share this topic