Hierarchical and recursive queries in SQL
A hierarchical query is a type of SQL query that handles hierarchical model data. They are special case of more general recursive fixpoint queries, which compute transitive closures.
In standard SQL:1999 hierarchical queries are implemented by way of recursive common table expressions (CTEs). Unlike the Oracle extension described below, the recursive CTEs were designed with fixpoint semantics from the beginning.[1] The recursive CTEs from the standard were relatively close to the existing implementation in IBM DB2 version 2.[2] Recursive CTEs are also supported by Microsoft SQL Server,[3] Firebird 2.1[4] , PostgreSQL 8.4+,[5] Oracle 11g Release 2 and CUBRID.
An alternative syntax is the non-standard CONNECT BY
construct; it was introduced by Oracle in the 1980s.[6] Prior to Oracle 10g, the construct was only useful for traversing acyclic graphs because it returned an error on detecting any cycles; in version 10g Oracle introduced the NOCYCLE feature (and keyword), making the traversal work in the presence of cycles as well.[7]
Contents |
CONNECT BY [edit]
"CONNECT BY" is supported by EnterpriseDB,[8] Oracle database,[9] CUBRID,[10] and DB2 although only if it is enabled as a compatibility mode.[11] Syntax:
SELECT select_list FROM table_expression [ WHERE ... ] [ START WITH start_expression ] CONNECT BY [NOCYCLE] { PRIOR parent_expr = child_expr | child_expr = PRIOR parent_expr } [ ORDER SIBLINGS BY column1 [ ASC | DESC ] [, column2 [ ASC | DESC ] ] ... [ GROUP BY ... ] [ HAVING ... ] ...
- For example
SELECT LEVEL, LPAD (' ', 2 * (LEVEL - 1)) || ename "employee", empno, mgr "manager" FROM emp START WITH mgr IS NULL CONNECT BY PRIOR empno = mgr;
The output from the above query would look like:
level | employee | empno | manager -------+-------------+-------+--------- 1 | KING | 7839 | 2 | JONES | 7566 | 7839 3 | SCOTT | 7788 | 7566 4 | ADAMS | 7876 | 7788 3 | FORD | 7902 | 7566 4 | SMITH | 7369 | 7902 2 | BLAKE | 7698 | 7839 3 | ALLEN | 7499 | 7698 3 | WARD | 7521 | 7698 3 | MARTIN | 7654 | 7698 3 | TURNER | 7844 | 7698 3 | JAMES | 7900 | 7698 2 | CLARK | 7782 | 7839 3 | MILLER | 7934 | 7782 (14 rows)
Pseudocolumns [edit]
- LEVEL
- CONNECT_BY_ISLEAF
- CONNECT_BY_ISCYCLE
Unary operators [edit]
- CONNECT_BY_ROOT
Functions [edit]
- SYS_CONNECT_BY_PATH
Common table expression [edit]
![]() |
This section requires expansion. (November 2012) |
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 DB2, Firebird,[12] Microsoft SQL Server, Oracle (with recursion since 11g release 2), PostgreSQL (since 8.4), HyperSQL and H2 (experimental).[13] Oracle calls CTEs "subquery factoring".[14]
Syntax:
WITH [RECURSIVE] with_query [, ...] SELECT...
with_query
looks like
with_query_name [ (column_name [,...]) ] AS (SELECT ...)
Recursive CTEs (or "recursive subquery factoring"[15] in Oracle lingo) can be use to traverse relations (as graphs or trees) although the syntax is much more involved because there are no automatic pseudocolums created (like LEVEL above); if these are desired, they have to be created in the code. See MSDN documentation[3] or IBM documentation[16][17] for tutorial examples.
The RECURSIVE keyword is not usually needed after WITH in systems other than PostgreSQL.[18]
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.[19] 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.[20]
An example of 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 -- Recursive Subquery WHERE n < 9) SELECT * FROM temp;
See also [edit]
- Datalog also implements fixpoint queries
- Deductive databases
- Hierarchical model
- Reachability
- Transitive closure
- Tree structure
References [edit]
- ^ Jim Melton; Alan R. Simon (2002). SQL:1999: Understanding Relational Language Components. Morgan Kaufmann. p. 343. ISBN 978-1-55860-456-8.
- ^ Jim Melton; Alan R. Simon (2002). SQL:1999: Understanding Relational Language Components. Morgan Kaufmann. p. 353. ISBN 978-1-55860-456-8.
- ^ a b Microsoft. "Recursive Queries Using Common Table Expressions". Retrieved 2009-12-23.
- ^ Helen Borrie (2008-07-15). "Firebird 2.1 Release Notes". Retrieved 2009-02-07.
- ^ "WITH Queries". PostgreSQL
- ^ Benedikt, M.; Senellart, P. (2011). "Databases". In Blum, Edward K.; Aho, Alfred V. Computer Science. The Hardware, Software and Heart of It. p. 189. doi:10.1007/978-1-4614-1168-0_10. ISBN 978-1-4614-1167-3.
- ^ Sanjay Mishra; Alan Beaulieu (2004). Mastering Oracle SQL. O'Reilly Media, Inc. p. 227. ISBN 978-0-596-00632-7.
- ^ Hierarchical Queries, EnterpriseDB
- ^ Hierarchical Queries, Oracle
- ^ "CUBRID Hierarchical Query". Retrieved 11 February 2013.
- ^ Jonathan Gennick (2010). SQL Pocket Guide (3rd ed.). O'Reilly Media, Inc. p. 8. ISBN 978-1-4493-9409-7.
- ^ Comparison of relational database management systems#Database capabilities
- ^ http://www.h2database.com/html/advanced.html#recursive_queries
- ^ Karen Morton; Robyn Sands; Jared Still; Riyaj Shamsudeen, Kerry Osborne (2010). Pro Oracle SQL. Apress. p. 283. ISBN 978-1-4302-3228-5.
- ^ Karen Morton; Robyn Sands; Jared Still; Riyaj Shamsudeen, Kerry Osborne (2010). Pro Oracle SQL. Apress. p. 304. ISBN 978-1-4302-3228-5.
- ^ http://publib.boulder.ibm.com/infocenter/dzichelp/v2r2/topic/com.ibm.db2z9.doc.apsg/src/tpc/db2z_xmprecursivecte.htm
- ^ http://publib.boulder.ibm.com/infocenter/iseries/v5r4/index.jsp?topic=%2Fsqlp%2Frbafyrecursivequeries.htm
- ^ Regina Obe; Leo Hsu (2012). PostgreSQL: Up and Running. O'Reilly Media. p. 94. ISBN 978-1-4493-2633-3.
- ^ Jim Melton; Alan R. Simon (2002). SQL:1999: Understanding Relational Language Components. Morgan Kaufmann. p. 352. ISBN 978-1-55860-456-8.
- ^ Don Chamberlin (1998). A Complete Guide to DB2 Universal Database. Morgan Kaufmann. pp. 253–254. ISBN 978-1-55860-482-7.
Further reading [edit]
- C. J. Date (2011). SQL and Relational Theory: How to Write Accurate SQL Code (2nd ed.). O'Reilly Media. pp. 159–163. ISBN 978-1-4493-1640-2.
Academic textbooks. Note that these cover only the SQL:1999 standard (and Datalog), but not the Oracle extension.
- Abraham Silberschatz; Henry Korth; S. Sudarshan (2010). Database System Concepts (6th ed.). McGraw-Hill. pp. 187–192. ISBN 978-0-07-352332-3.
- Raghu Ramakrishnan; Johannes Gehrke (2003). Database management systems (3rd ed.). McGraw-Hill. ISBN 978-0-07-246563-1. Chapter 24.
- Hector Garcia-Molina; Jeffrey D. Ullman; Jennifer Widom (2009). Database systems: the complete book (2nd ed.). Pearson Prentice Hall. pp. 437–445. ISBN 978-0-13-187325-4.
External links [edit]
- http://stackoverflow.com/questions/1731889/cycle-detection-with-recursive-subquery-factoring
- http://explainextended.com/2009/11/18/sql-server-are-the-recursive-ctes-really-set-based/
- http://gennick.com/with.html
- http://www.cs.duke.edu/courses/fall04/cps116/lectures/11-recursion.pdf
|