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.
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:
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;
WITH
Clause: Used to define the CTE.cte_name
: Name of the CTE; must be unique within the query.
WITH EmployeeCTE AS (
SELECT name, salary, department_id
FROM employees
WHERE salary > 50000
)
SELECT name, department_id
FROM EmployeeCTE;
EmployeeCTE
contains employees earning more than 50,000.Name | Department_ID |
---|---|
Alice | 1 |
Bob | 2 |
A single CTE defines one temporary result set.
WITH EmployeeCTE AS (
SELECT name, department_id
FROM employees
WHERE department_id = 1
)
SELECT *
FROM EmployeeCTE;
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;
Name | Department_Name |
---|---|
Alice | Engineering |
Bob | Sales |
CTEs can be used in various SQL operations, including SELECT
, INSERT
, UPDATE
, and DELETE
.
SELECT
WITH HighSalary AS (
SELECT name, salary
FROM employees
WHERE salary > 70000
)
SELECT name
FROM HighSalary;
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;
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;
DELETE
WITH ToBeDeleted AS (
SELECT id
FROM employees
WHERE salary < 30000
)
DELETE FROM employees
WHERE id IN (SELECT id FROM ToBeDeleted);
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;
Department_ID | Avg_Salary |
---|---|
1 | 75000 |
2 | 68000 |
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;
Department_Name | Num_Employees |
---|---|
Sales | 5 |
HR | 3 |
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;
Feature | CTE | Subquery | Temporary Table |
---|---|---|---|
Scope | Single query block | Single query block | Across multiple queries |
Readability | High | Moderate | Moderate |
Reusability | High | Low | High |
Performance Impact | Optimized by SQL engine | May execute repeatedly | Depends on implementation |
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!❤️