136 lines
8.3 KiB
HTML
136 lines
8.3 KiB
HTML
|
<?xml version="1.0" encoding="UTF-8"?>
|
||
|
<!DOCTYPE html
|
||
|
PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
||
|
<html lang="en-us" xml:lang="en-us">
|
||
|
<head>
|
||
|
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
|
||
|
<meta name="security" content="public" />
|
||
|
<meta name="Robots" content="index,follow" />
|
||
|
<meta http-equiv="PICS-Label" content='(PICS-1.1 "http://www.icra.org/ratingsv02.html" l gen true r (cz 1 lz 1 nz 1 oz 1 vz 1) "http://www.rsac.org/ratingsv01.html" l gen true r (n 0 s 0 v 0 l 0) "http://www.classify.org/safesurf/" l gen true r (SS~~000 1))' />
|
||
|
<meta name="DC.Type" content="reference" />
|
||
|
<meta name="DC.Title" content="Recursive query example" />
|
||
|
<meta name="abstract" content="A recursive query is one that is defined by a Union All with an initialization fullselect that seeds the recursion and an iterative fullselect that contains a direct reference to itself in the FROM clause." />
|
||
|
<meta name="description" content="A recursive query is one that is defined by a Union All with an initialization fullselect that seeds the recursion and an iterative fullselect that contains a direct reference to itself in the FROM clause." />
|
||
|
<meta name="DC.Relation" scheme="URI" content="rzajqrecursive.htm" />
|
||
|
<meta name="copyright" content="(C) Copyright IBM Corporation 1998, 2006" />
|
||
|
<meta name="DC.Rights.Owner" content="(C) Copyright IBM Corporation 1998, 2006" />
|
||
|
<meta name="DC.Format" content="XHTML" />
|
||
|
<meta name="DC.Identifier" content="rzajqrcteexample" />
|
||
|
<meta name="DC.Language" content="en-us" />
|
||
|
<!-- All rights reserved. Licensed Materials Property of IBM -->
|
||
|
<!-- US Government Users Restricted Rights -->
|
||
|
<!-- Use, duplication or disclosure restricted by -->
|
||
|
<!-- GSA ADP Schedule Contract with IBM Corp. -->
|
||
|
<link rel="stylesheet" type="text/css" href="./ibmdita.css" />
|
||
|
<link rel="stylesheet" type="text/css" href="./ic.css" />
|
||
|
<title>Recursive query example</title>
|
||
|
</head>
|
||
|
<body id="rzajqrcteexample"><a name="rzajqrcteexample"><!-- --></a>
|
||
|
<!-- Java sync-link --><script language="Javascript" src="../rzahg/synch.js" type="text/javascript"></script>
|
||
|
<h1 class="topictitle1">Recursive query example</h1>
|
||
|
<div><p>A recursive query is one that is defined by a Union All with an
|
||
|
initialization fullselect that seeds the recursion and an iterative fullselect
|
||
|
that contains a direct reference to itself in the FROM clause.</p>
|
||
|
<div class="section"><p>There are additional restrictions as to what can be specified
|
||
|
in the definition of a recursive query and those restrictions can be found
|
||
|
in the SQL Programming. A key restriction is that query functions like grouping,
|
||
|
aggregation or distinct that require a materialization of all the qualifying
|
||
|
records before performing the function cannot be allowed within the iterative
|
||
|
fullselect itself and must be requested in the main query, allowing the recursion
|
||
|
to complete.</p>
|
||
|
<p>The following is an example of a recursive query over a
|
||
|
table called flights, that contains information about departure and arrival
|
||
|
cities. The query returns all the flight destinations available by recursion
|
||
|
from the two specified cities (New York and Chicago) and the number of connections
|
||
|
and total cost to arrive at that final destination.</p>
|
||
|
<p>Because this example
|
||
|
uses the recursion process to also accumulate information like the running
|
||
|
cost and number of connections, four values are actually put on the queue
|
||
|
entry. These values are:</p>
|
||
|
<ul><li>The originating departure city (either Chicago or New York) because it
|
||
|
remains fixed from the start of the recursion</li>
|
||
|
<li>The arrival city which is used for subsequent joins</li>
|
||
|
<li>The incrementing connection count</li>
|
||
|
<li>The accumulating total cost to reach each destination</li>
|
||
|
</ul>
|
||
|
<p>Typically the data needed for the queue entry is less then the full
|
||
|
record (sometimes much less) although that is not the case for this example.</p>
|
||
|
</div>
|
||
|
<div class="example"><pre><strong>CREATE TABLE</strong> flights
|
||
|
(
|
||
|
departure <strong>CHAR (10) NOT NULL WITH DEFAULT</strong>,
|
||
|
arrival <strong>CHAR (10) NOT NULL WITH DEFAULT</strong>,
|
||
|
carrier <strong>CHAR (15) NOT NULL WITH DEFAULT</strong>,
|
||
|
flight_num <strong>CHAR (5) NOT NULL WITH DEFAULT</strong>,
|
||
|
ticket <strong>INT NOT NULL WITH DEFAULT</strong>)
|
||
|
|
||
|
<strong>WITH</strong> destinations (departure, arrival, connects, cost ) <strong>AS</strong>
|
||
|
(
|
||
|
<strong>SELECT</strong> f.departure,f.arrival, 0, ticket
|
||
|
<strong>FROM</strong> flights f
|
||
|
<strong>WHERE</strong> f.departure = 'Chicago' <strong>OR</strong>
|
||
|
f.departure = 'New York'
|
||
|
<strong>UNION ALL</strong>
|
||
|
<strong>SELECT</strong>
|
||
|
r.departure, b.arrival, r.connects + 1,
|
||
|
r.cost + b.ticket
|
||
|
<strong>FROM</strong> destinations r, flights b
|
||
|
<strong>WHERE</strong> r.arrival = b.departure
|
||
|
)
|
||
|
<strong>SELECT DISTINCT</strong> departure, arrival, connects, cost
|
||
|
<strong>FROM</strong> destinations
|
||
|
</pre>
|
||
|
</div>
|
||
|
<div class="section"><p>The following is the initialization fullselect of the above query.
|
||
|
It seeds the rows that will start the recursion process. It provides the
|
||
|
initial destinations (arrival cities) that are a direct flight from Chicago
|
||
|
or New York.</p>
|
||
|
<pre><strong>SELECT</strong> f.departure,f.arrival, 0, ticket
|
||
|
<strong>FROM</strong> flights f
|
||
|
<strong>WHERE</strong> f.departure='Chicago' <strong>OR</strong>
|
||
|
f.departure='New York'</pre>
|
||
|
<p>The following is the iterative fullselect of the above query.
|
||
|
It contains a single reference in the FROM clause to the destinations recursive
|
||
|
common table expression and will source further recursive joins to the same
|
||
|
flights table. The arrival values of the parent row (initially direct flights
|
||
|
from New York or Chicago) are joined with the departure value of the subsequent
|
||
|
child rows. It is important to identify the correct parent/child relationship
|
||
|
on the recursive join predicate or infinite recursion can occur. Other local
|
||
|
predicates can also be used to limit the recursion. For example, if you want
|
||
|
a limit of at most 3 connecting flights, a local predicate using the accumulating
|
||
|
connection count, r.connects<=3, can be specified. </p>
|
||
|
</div>
|
||
|
<div class="section"><pre><strong>SELECT</strong>
|
||
|
r.departure, b.arrival, r.connects + 1 ,
|
||
|
r.cost + b.ticket
|
||
|
<strong>FROM</strong> destinations r, flights b
|
||
|
<strong>WHERE</strong> r.arrival=b.departure</pre>
|
||
|
<p>The main query is the query that references the recursive common
|
||
|
table expression or view. It is in the main query where requests like grouping,
|
||
|
ordering and distinct will be specified. </p>
|
||
|
<pre><strong>SELECT DISTINCT</strong> departure, arrival, connects, cost
|
||
|
<strong>FROM</strong> destinations </pre>
|
||
|
</div>
|
||
|
<div class="section"><h4 class="sectiontitle">Implementation considerations</h4><p>To implement a source
|
||
|
for the recursion, a new temporary data object is provided called a queue.
|
||
|
As rows meet the requirements of either the initialization fullselect or
|
||
|
the iterative fullselect and are pulled up through the union all, values
|
||
|
necessary to feed the continuing recursion process are captured and placed
|
||
|
in an entry on the queue , an enqueue operation. At query runtime, the queue
|
||
|
data source then takes the place of the recursive reference in the common
|
||
|
table expression or view. The iterative fullselect processing ends when the
|
||
|
queue is exhausted of entries or a fetch N rows limitation has been met.
|
||
|
Because the recursive queue feeds the recursion process and holds transient
|
||
|
data, the join between the dequeue of these queue entries and the rest of
|
||
|
the fullselect tables will always be a constrained join, with the queue on
|
||
|
the left.</p>
|
||
|
</div>
|
||
|
<div class="section"><img src="rzajq563.gif" alt="Visual Explain diagram" /></div>
|
||
|
</div>
|
||
|
<div>
|
||
|
<div class="familylinks">
|
||
|
<div class="parentlink"><strong>Parent topic:</strong> <a href="rzajqrecursive.htm" title="Certain applications and data are recursive by nature. Examples of such applications are a bill-of-material, reservation, trip planner or networking planning system where data in one results row has a natural relationship (call it a parent, child relationship) with data in another row or rows. Although the kinds of recursion implemented in these systems can be performed by using SQL Stored Procedures and temporary results tables, the use of a recursive query to facilitate the access of this hierarchical data can lead to a more elegant and better performing application.">Recursive query optimization</a></div>
|
||
|
</div>
|
||
|
</div>
|
||
|
</body>
|
||
|
</html>
|