Lecture
A hierarchical query is a type of SQL query that processes data organized in a hierarchical model. These are special cases of the more general fixed-point recursive queries, which compute transitive closures.
In standard SQL:1999, hierarchical queries are implemented using recursive common table expressions (CTEs). Unlike Oracle's earlier CONNECT BY clause, recursive CTEs were designed from the outset with fixed-point semantics. The standard's recursive CTEs were relatively close to the existing implementation in IBM DB2 version 2. Recursive CTEs are also supported by Microsoft SQL Server (starting with SQL Server 2008 R2), Firebird 2.1, PostgreSQL 8.4+, SQLite 3.8.3+, IBM Informix version 11.50+, CUBRID, and MySQL 8.0.1+. Tableau and TIBCO Spotfire do not support CTEs, while Oracle 11g Release 2's implementation lacks fixed-point semantics.
Without common table expressions or CONNECT BY clauses, it is still possible to perform hierarchical queries using custom recursive functions.
WITH provides a way to write auxiliary statements for use in a larger query. These statements, also called common table expressions (CTEs), can be thought of as defining temporary tables that exist only for a single query. The auxiliary statement in a WITH clause can be a SELECT, INSERT, UPDATE, or DELETE, and the WITH clause itself is attached to a primary statement, which can also be a SELECT, INSERT, UPDATE, or DELETE.
A CTE plays the role of an SQL view that is created within the scope of a single query and is not persisted as a schema object.
A common table expression (CTE) can be thought of as a temporary result set defined within the scope of a single SELECT, INSERT, UPDATE, DELETE, or CREATE VIEW statement. A CTE is similar to a derived table in that it is not stored as an object and is only in effect for the duration of the query. However, unlike a derived table, a CTE can be self-referencing and can be referenced multiple times within the same query.
Everything works similarly to using a view, except for the required parentheses enclosing the query; formally, it is enough to replace CREATE VIEW with WITH. As with a view, the parentheses after the CTE name may contain a list of columns, if we need to include only some of them from the underlying query and/or rename them
A CTE can be used to:
Using a CTE offers the benefits of improved readability and easier maintenance of complex queries. A query can be broken up into separate, simple, logical building blocks. These simple blocks can then be used to build up more complex temporary CTEs until the final result set is produced.

A common table expression, or CTE, (in SQL) is a temporary named result set derived from a simple query and defined within the scope of the execution of a SELECT, INSERT, UPDATE, or DELETE statement.
A CTE can be thought of as an alternative to derived tables (subqueries), views, and inline user-defined functions.
Common table expressions are supported by Teradata, DB2, [[Firebird], Microsoft SQL Server, Oracle (with recursion starting in version 11g Release 2), PostgreSQL (starting with 8.4), MariaDB (starting with 10.2), MySQL (starting with 8.0), SQLite (starting with 3.8.3), HyperSQL, and H2 (experimental). Oracle calls CTEs «subquery factoring».
The syntax for a recursive CTE is as follows:
where the syntax of with_query is:
Recursive CTEs (or «recursive subquery factoring»[10] in Oracle's terminology) can be used to traverse relationships (represented as graphs or trees), although the syntax is considerably more complex, since no automatic pseudo-columns are generated (such as LEVEL below); if these are desired, they must be created in code. See the MSDN documentation or IBM documentation[11] for tutorial examples.
The keyword RECURSIVE is generally not required after WITH in systems other than PostgreSQL.[12]
In SQL:1999, a recursive (CTE) query may appear anywhere a query is allowed. For example, one can name the result using CREATE [RECURSIVE] VIEW. Using a CTE inside INSERT INTO, a table can be populated with data generated from a recursive query; random data generation is possible using this technique without resorting to procedural statements.[13]
Some databases, such as PostgreSQL, support a shorter CREATE RECURSIVE VIEW form, which is internally translated into WITH RECURSIVE syntax. [14]
An example of a recursive query that computes the factorial of the numbers from 0 to 9 is as follows:
An alternative, non-standard syntax is the CONNECT BY construct; it was introduced by Oracle in the 1980s. Before Oracle 10g, this construct was only useful for traversing acyclic graphs, since it returned an error when any cycles were detected; in version 10g, Oracle introduced the NOCYCLE function (and keyword), thanks to which traversal works even in the presence of cycles.[15]
CONNECT BY is supported by EnterpriseDB, Oracle Database,[16] CUBRID,[17] IBM Informix, and DB2, though only when enabled as a compatibility mode. The syntax is as follows:
The output of the above query would look as follows:
The following example returns the surname of each employee in department 10, each manager above that employee in the hierarchy, the number of levels between the manager and the employee, and the path between them:
Recursive common table expressions (CTEs) were an implementation of the SQL:1999 standard for hierarchical queries. The first implementations of recursive CTEs began to appear in 2007. The standard's recursive CTEs were relatively close to the existing implementation in IBM DB2 version 2. Recursive CTEs were eventually supported by Microsoft SQL Server (starting with SQL Server 2008 R2), Firebird 2.1, PostgreSQL 8.4+, SQLite 3.8.3+, Oracle 11g Release 2, and IBM Informix version 11.50+.
Without common table expressions or CONNECT BY expressions, it is still possible to perform hierarchical queries using custom recursive functions, but these tend to result in very complex SQL.
Evaluating a recursive query
The non-recursive part is evaluated. For UNION (but not UNION ALL), duplicate rows are discarded. All remaining rows are included in the recursive query's result and are also placed into a temporary working table.
While the working table is not empty, the following steps are repeated:
The recursive part is evaluated such that the recursive reference to the query itself refers to the current contents of the working table. For UNION (but not UNION ALL), duplicate rows and rows duplicating previously obtained rows are discarded. All remaining rows are included in the recursive query's result and are also placed into a temporary intermediate table.
The contents of the working table are replaced with the contents of the intermediate table, and the intermediate table is then cleared.
Strictly speaking, this process is iterative, not recursive, but the SQL standards committee chose the term RECURSIVE.
In MariaDB, a non-recursive CTE is essentially treated as a local view for the query, whose syntax is more readable than a nested FROM (SELECT…). A CTE can reference another and can itself be referenced from multiple places.
Thus, CTEs are similar to derived tables. For example:
SQL with a derived table:
SQL with a CTE:
SQL is generally poor at recursion. One of the advantages of CTEs is that they allow a query to reference itself, and thus enable recursive SQL. A recursive CTE will repeatedly execute against subsets of the data until it obtains the complete result set. This makes it especially useful for processing hierarchical or tree-structured data.
With recursive CTEs, you can accomplish things that would be very difficult to do with standard SQL, and with higher execution speed. They can help solve many types of business problems and even simplify some complex SQL/application logic down to a simple recursive database call.
Some example use cases for recursive CTEs are: finding gaps in data, generating organizational charts, and generating test data.
WITH RECURSIVE denotes a recursive CTE. It is given a name, followed by a body (the main query):
Below is a recursive CTE that counts from 1 to 50.
The above statement prints a series of numbers from 1 to 49.
MySQL 8.0 adds CTEs via the standard WITH keyword, in much the same way as it is implemented in competing products.
To specify common table expressions, use a WITH clause containing one or more comma-separated subclauses. Each subclause provides a subquery that produces a result set and associates a name with the subquery. The following example defines CTEs named cte1 and cte2 in the WITH clause and references them in the top-level SELECT that follows the WITH clause:
Immediately before SELECT for statements that include a SELECT statement:
A recursive common table expression – is an expression having a subquery that refers to its own name. For example:
+------+ | n | +------+ | 1 | | 2 | | 3 | | 4 | | 5 | +------+
Comments