Syntax and Usage of CTEs

A Common Table Expression (CTE) is a feature in SQL that allows you to define a temporary named result set for use in a single SQL query. It improves query readability, maintainability, and performance in certain cases.

Introduction to CTEs

CTEs provide a way to improve the organization of SQL queries by creating temporary, reusable result sets. They are defined using the WITH keyword and are primarily used to:

  • Simplify complex queries.
  • Enhance query readability.
  • Facilitate hierarchical and recursive data analysis.

Syntax of CTEs

The general syntax for a CTE is as follows:

				
					WITH cte_name (column1, column2, ...) AS (
    SELECT columns
    FROM table
    WHERE conditions
)
SELECT columns
FROM cte_name;

				
			

Key Points:

  1. WITH Clause: Used to define the CTE.
  2. cte_name: Name of the CTE; must be unique within the query.
  3. Optional Column Names: Specifies column aliases (useful when the CTE query changes column names).
  4. Main Query: The query that uses the CTE.

Understanding CTE Components

Example:

				
					WITH EmployeeCTE AS (
    SELECT name, salary, department_id
    FROM employees
    WHERE salary > 50000
)
SELECT name, department_id
FROM EmployeeCTE;

				
			

Explanation:

  1. EmployeeCTE contains employees earning more than 50,000.
  2. The main query fetches their names and departments.

Output:

NameDepartment_ID
Alice1
Bob2

Single vs. Multiple CTEs

Single CTE:

A single CTE defines one temporary result set.

				
					WITH EmployeeCTE AS (
    SELECT name, department_id
    FROM employees
    WHERE department_id = 1
)
SELECT * 
FROM EmployeeCTE;

				
			

Multiple CTEs:

You can define multiple CTEs within the same query by separating them with commas.

				
					WITH DepartmentCTE AS (
    SELECT department_id, department_name
    FROM departments
),
EmployeeCTE AS (
    SELECT name, department_id
    FROM employees
    WHERE salary > 60000
)
SELECT e.name, d.department_name
FROM EmployeeCTE e
JOIN DepartmentCTE d ON e.department_id = d.department_id;

				
			

Output:

NameDepartment_Name
AliceEngineering
BobSales

Using CTEs in Different Query Types

CTEs can be used in various SQL operations, including SELECT, INSERT, UPDATE, and DELETE.

Using CTE with SELECT

				
					WITH HighSalary AS (
    SELECT name, salary
    FROM employees
    WHERE salary > 70000
)
SELECT name
FROM HighSalary;

				
			

Using CTE with INSERT

				
					WITH NewEmployees AS (
    SELECT 'Jane' AS name, 55000 AS salary, 3 AS department_id
)
INSERT INTO employees (name, salary, department_id)
SELECT name, salary, department_id
FROM NewEmployees;

				
			

Using CTE with UPDATE

				
					WITH SalaryUpdate AS (
    SELECT id, salary * 1.10 AS new_salary
    FROM employees
    WHERE department_id = 1
)
UPDATE employees
SET salary = new_salary
FROM SalaryUpdate
WHERE employees.id = SalaryUpdate.id;

				
			

Using CTE with DELETE

				
					WITH ToBeDeleted AS (
    SELECT id
    FROM employees
    WHERE salary < 30000
)
DELETE FROM employees
WHERE id IN (SELECT id FROM ToBeDeleted);

				
			

Examples of CTE Usage

Aggregations with CTEs

				
					WITH AvgSalary AS (
    SELECT department_id, AVG(salary) AS avg_salary
    FROM employees
    GROUP BY department_id
)
SELECT department_id, avg_salary
FROM AvgSalary
WHERE avg_salary > 50000;

				
			

Output:

Department_IDAvg_Salary
175000
268000

Joining CTEs with Tables

				
					WITH EmployeeCount AS (
    SELECT department_id, COUNT(*) AS num_employees
    FROM employees
    GROUP BY department_id
)
SELECT d.department_name, ec.num_employees
FROM departments d
JOIN EmployeeCount ec ON d.department_id = ec.department_id;

				
			

Output:

Department_NameNum_Employees
Sales5
HR3

Advanced CTE Concepts

Recursive CTEs

Recursive CTEs enable hierarchical queries.

Example: Organizational hierarchy.

				
					WITH OrgHierarchy AS (
    SELECT id, name, manager_id, 1 AS level
    FROM employees
    WHERE manager_id IS NULL
    UNION ALL
    SELECT e.id, e.name, e.manager_id, oh.level + 1
    FROM employees e
    INNER JOIN OrgHierarchy oh ON e.manager_id = oh.id
)
SELECT * 
FROM OrgHierarchy;

				
			

Comparison of CTEs with Subqueries and Temporary Tables

FeatureCTESubqueryTemporary Table
ScopeSingle query blockSingle query blockAcross multiple queries
ReadabilityHighModerateModerate
ReusabilityHighLowHigh
Performance ImpactOptimized by SQL engineMay execute repeatedlyDepends on implementation

Limitations and Best Practices

Limitations

  1. Scope: Limited to the query where it’s defined.
  2. Performance: May not always be optimal for large datasets.

Best Practices

  1. Use descriptive names for CTEs and columns.
  2. Avoid overly complex CTEs that hinder performance.
  3. Test query execution plans for efficiency.

CTEs are a powerful tool in SQL for simplifying and structuring complex queries. By understanding their syntax, use cases, and best practices, you can leverage CTEs to create efficient and readable SQL code. Happy Coding!❤️

Table of Contents