Understanding CTEs (Common Table Expressions) in SQL
James Reed
Infrastructure Engineer · Leapcell

Key Takeaways
- CTEs improve SQL query readability and organization.
- Recursive CTEs help handle hierarchical data easily.
- CTEs are widely supported but may not always improve performance.
Introduction
Structured Query Language (SQL) is a powerful tool for managing and querying relational databases. Among its many features, the Common Table Expression (CTE) stands out as an elegant and effective way to organize complex queries. Introduced in SQL:1999 and widely supported by modern database systems such as Microsoft SQL Server, PostgreSQL, MySQL (from version 8.0), and Oracle, CTEs offer both readability and flexibility.
What is a CTE?
A Common Table Expression (CTE) is a temporary result set defined within the execution scope of a single SQL statement. Think of it as a named query that you can reference within a SELECT, INSERT, UPDATE, or DELETE statement. Unlike subqueries, CTEs can improve readability, support recursion, and allow you to break down complex operations into simpler, more maintainable parts.
Syntax of a CTE
The basic syntax of a CTE is as follows:
WITH cte_name (column1, column2, ...) AS ( SELECT ... FROM ... WHERE ... ) SELECT * FROM cte_name;
- The
WITH
keyword introduces the CTE. cte_name
is the name you give to your temporary result set.- Inside the parentheses, you may optionally specify column names.
- The SELECT statement inside the parentheses defines the data for the CTE.
Example: Using a Simple CTE
Suppose you have a table called Employees
and you want to find all employees who earn more than the average salary. Using a CTE, you can write:
WITH AverageSalary AS ( SELECT AVG(Salary) AS AvgSalary FROM Employees ) SELECT Name, Salary FROM Employees, AverageSalary WHERE Employees.Salary > AverageSalary.AvgSalary;
This approach makes the query easier to read and maintain compared to a traditional subquery.
Recursive CTEs
One of the most powerful uses of CTEs is recursion. Recursive CTEs allow you to perform hierarchical or tree-structured queries, such as finding all subordinates of a manager in an organizational chart.
Here is a simple example:
WITH RecursiveCTE AS ( SELECT EmployeeID, ManagerID, Name FROM Employees WHERE ManagerID IS NULL -- Start with the top manager(s) UNION ALL SELECT e.EmployeeID, e.ManagerID, e.Name FROM Employees e INNER JOIN RecursiveCTE r ON e.ManagerID = r.EmployeeID ) SELECT * FROM RecursiveCTE;
This query will return all employees, organized by their managerial hierarchy.
Advantages of Using CTEs
- Improved Readability: By giving a name to subqueries, you can make your SQL code much more readable and maintainable.
- Modularization: You can break down complex queries into logical building blocks.
- Recursive Queries: Recursive CTEs are invaluable for working with hierarchical data.
- Reuse: You can reference the same CTE multiple times within a query.
Limitations and Considerations
- Scope: CTEs are only visible within the statement in which they are defined.
- Performance: While CTEs improve readability, in some cases, they may not offer performance benefits over subqueries or derived tables. Always check the query plan and optimize as needed.
- Unsupported Features: Some older database systems or earlier versions may not support CTEs.
Conclusion
CTEs are a versatile and essential feature of modern SQL. They help simplify complex queries, enable recursion, and improve the overall organization of your SQL code. By mastering CTEs, you can write more efficient, readable, and maintainable SQL queries.
FAQs
A CTE is a temporary result set for organizing complex queries.
CTEs make SQL queries easier to read and maintain.
Most modern databases support CTEs, but older versions may not.
We are Leapcell, your top choice for hosting backend projects.
Leapcell is the Next-Gen Serverless Platform for Web Hosting, Async Tasks, and Redis:
Multi-Language Support
- Develop with Node.js, Python, Go, or Rust.
Deploy unlimited projects for free
- pay only for usage — no requests, no charges.
Unbeatable Cost Efficiency
- Pay-as-you-go with no idle charges.
- Example: $25 supports 6.94M requests at a 60ms average response time.
Streamlined Developer Experience
- Intuitive UI for effortless setup.
- Fully automated CI/CD pipelines and GitOps integration.
- Real-time metrics and logging for actionable insights.
Effortless Scalability and High Performance
- Auto-scaling to handle high concurrency with ease.
- Zero operational overhead — just focus on building.
Explore more in the Documentation!
Follow us on X: @LeapcellHQ