A common table expression, or CTE, (in
SQL) is a temporary named result set, derived from a simple query and defined within the execution scope of a SELECT, INSERT, UPDATE, or DELETE statement. CTEs can be thought of as alternatives to derived tables (
subquery),
views, and inline user-defined functions. Common table expressions are supported by
Teradata (starting with version 14),
IBM Db2,
Informix (starting with version 14.1),
Firebird (starting with version 2.1),
Microsoft SQL Server (starting with version 2005),
Oracle (with recursion since 11g release 2),
PostgreSQL (since 8.4),
MariaDB (since 10.2),
MySQL (since 8.0),
SQLite (since 3.8.3),
HyperSQL,
Informix (since 14.10), Google
BigQuery,
Sybase (starting with version 9),
Vertica,
H2 (experimental), and
many others. Oracle calls CTEs "subquery factoring". The syntax for a CTE (which may or may not be recursive) is as follows: WITH [RECURSIVE] with_query [, ...] SELECT ... where with_query's syntax is: query_name [ (column_name [,...]) ] AS (SELECT ...) Recursive CTEs can be used to traverse relations (as graphs or trees) although the syntax is much more involved because there are no automatic pseudo-columns created (like LEVEL
below); if these are desired, they have to be created in the code. See MSDN documentation for tutorial examples. The RECURSIVE keyword is not usually needed after WITH in systems other than PostgreSQL. In SQL:1999 a recursive (CTE) query may appear anywhere a query is allowed. It's possible, for example, to name the result using CREATE [RECURSIVE] VIEW. Using a CTE inside an INSERT INTO, one can populate a table with data generated from a recursive query; random data generation is possible using this technique without using any procedural statements. Some Databases, like PostgreSQL, support a shorter CREATE RECURSIVE VIEW format which is internally translated into WITH RECURSIVE coding. An example of a recursive query computing the
factorial of numbers from 0 to 9 is the following: WITH recursive temp (n, fact) AS ( SELECT 0, 1 -- Initial Subquery UNION ALL SELECT n+1, (n+1)*fact FROM temp WHERE n == CONNECT BY ==