Recursive Queries in SQL refer to queries that repeatedly execute until they reach a certain condition. They are useful for hierarchical data, such as a company’s organizational structure or a family tree. Recursive queries use a WITH RECURSIVE clause in SQL.
The basic syntax for recursive queries is as follows:
WITH RECURSIVE cte_name (column1, column2, ...) AS (
-- non-recursive term
SELECT column1, column2, ...
FROM table_name
WHERE condition
UNION ALL
-- recursive term
SELECT column1, column2, ...
FROM cte_name
JOIN table_name ON ...
WHERE condition
)
SELECT column1, column2, ...
FROM cte_name;
Here, cte_name
is the name of the Common Table Expression (CTE), and column1
, column2
, etc. are the columns you want to select. The table_name
and condition
parameters are the same as in regular SQL queries.
The WITH RECURSIVE clause has two parts: the non-recursive term and the recursive term. The non-recursive term is executed once at the beginning of the query, while the recursive term is executed repeatedly until it reaches a certain condition.
Let’s look at an example to better understand how recursive queries work. Suppose we have the following table of employees in a company:
CREATE TABLE employees (
id INTEGER PRIMARY KEY,
name TEXT NOT NULL,
manager_id INTEGER REFERENCES employees(id)
);
INSERT INTO employees (id, name, manager_id) VALUES
(1, 'Alice', NULL),
(2, 'Bob', 1),
(3, 'Charlie', 2),
(4, 'Dave', 3),
(5, 'Eve', 2),
(6, 'Frank', 1),
(7, 'Grace', 6),
(8, 'Heidi', 7),
(9, 'Ivan', 7);
We can use a recursive query to generate a report of all the employees in the company and their managers. The non-recursive term selects the top-level employees (those without a manager), while the recursive term selects the employees that report to each top-level employee.
WITH RECURSIVE employee_hierarchy (id, name, level) AS (
-- non-recursive term
SELECT id, name, 0
FROM employees
WHERE manager_id IS NULL
UNION ALL
-- recursive term
SELECT e.id, e.name, eh.level + 1
FROM employee_hierarchy eh
JOIN employees e ON e.manager_id = eh.id
)
SELECT id, name, level
FROM employee_hierarchy;
The output of this query would be:
id name level
--------------------
1 Alice 0
2 Bob 1
6 Frank 1
3 Charlie 2
5 Eve 2
7 Grace 2
4 Dave 3
8 Heidi 3
9 Ivan 3
As you can see, the query has generated a report of all the employees in the company, along with their level in the organizational structure.
Recursive queries can be very powerful for handling hierarchical data, but they can also be computationally expensive and difficult to understand. It’s important to use them judiciously and to make sure that they are optimized for performance.