forked from docs/doc-exports
Reviewed-by: Pruthi, Vineet <vineet.pruthi@t-systems.com> Co-authored-by: Lu, Huayi <luhuayi@huawei.com> Co-committed-by: Lu, Huayi <luhuayi@huawei.com>
237 lines
42 KiB
HTML
237 lines
42 KiB
HTML
<a name="EN-US_TOPIC_0000001637921145"></a><a name="EN-US_TOPIC_0000001637921145"></a>
|
|
|
|
<h1 class="topictitle1">WITH Expression</h1>
|
|
<div id="body8662426"><p id="EN-US_TOPIC_0000001637921145__en-us_topic_0000001637281285_p968917141273">The WITH expression is used to define auxiliary statements used in large queries. These auxiliary statements are usually called common table expressions (CTE), which can be understood as a named subquery. The subquery can be referenced multiple times by its name in the quey.</p>
|
|
<p id="EN-US_TOPIC_0000001637921145__en-us_topic_0000001637281285_p61451141320">An auxiliary statement may use <strong id="EN-US_TOPIC_0000001637921145__b10816153111114">SELECT</strong>, <strong id="EN-US_TOPIC_0000001637921145__b6557153317112">INSERT</strong>, <strong id="EN-US_TOPIC_0000001637921145__b4380103519110">UPDATE</strong>, or <strong id="EN-US_TOPIC_0000001637921145__b194889371716">DELETE</strong>. The <strong id="EN-US_TOPIC_0000001637921145__b4180651212">WITH</strong> clause can be attached to a main statement, which can be a <strong id="EN-US_TOPIC_0000001637921145__b54250713212">SELECT</strong>, <strong id="EN-US_TOPIC_0000001637921145__b1861639221">INSERT</strong>, or <strong id="EN-US_TOPIC_0000001637921145__b94221311022">DELETE </strong>statement.</p>
|
|
<div class="section" id="EN-US_TOPIC_0000001637921145__en-us_topic_0000001637281285_section266316326120"><h4 class="sectiontitle">SELECT in WITH</h4><p id="EN-US_TOPIC_0000001637921145__en-us_topic_0000001637281285_p129783818305">This section describes the usage of <strong id="EN-US_TOPIC_0000001637921145__b152131656928">SELECT</strong> in a <strong id="EN-US_TOPIC_0000001637921145__b2077260339">WITH</strong> clause.</p>
|
|
<p id="EN-US_TOPIC_0000001637921145__en-us_topic_0000001637281285_p0536113914314"><strong id="EN-US_TOPIC_0000001637921145__en-us_topic_0000001637281285_b9228124617314">Syntax</strong></p>
|
|
<div class="codecoloring" codetype="Sql" id="EN-US_TOPIC_0000001637921145__en-us_topic_0000001637281285_screen163112625715"><div class="highlight"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre><span class="normal">1</span></pre></div></td><td class="code"><div><pre><span></span><span class="p">[</span><span class="k">WITH</span><span class="w"> </span><span class="p">[</span><span class="k">RECURSIVE</span><span class="p">]</span><span class="w"> </span><span class="n">with_query</span><span class="w"> </span><span class="p">[,</span><span class="w"> </span><span class="p">...]</span><span class="w"> </span><span class="p">]</span><span class="w"> </span><span class="k">SELECT</span><span class="w"> </span><span class="p">...</span>
|
|
</pre></div></td></tr></table></div>
|
|
|
|
</div>
|
|
<p id="EN-US_TOPIC_0000001637921145__en-us_topic_0000001637281285_p1132206195713">The syntax of <strong id="EN-US_TOPIC_0000001637921145__b912210396313">with_query</strong> is as follows:</p>
|
|
<div class="codecoloring" codetype="Sql" id="EN-US_TOPIC_0000001637921145__en-us_topic_0000001637281285_screen43266115714"><div class="highlight"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre><span class="normal">1</span></pre></div></td><td class="code"><div><pre><span></span><span class="n">with_query_name</span><span class="w"> </span><span class="p">[</span><span class="w"> </span><span class="p">(</span><span class="w"> </span><span class="k">column_name</span><span class="w"> </span><span class="p">[,</span><span class="w"> </span><span class="p">...]</span><span class="w"> </span><span class="p">)</span><span class="w"> </span><span class="p">]</span><span class="k">AS</span><span class="w"> </span><span class="p">(</span><span class="w"> </span><span class="err">{</span><span class="k">select</span><span class="w"> </span><span class="o">|</span><span class="w"> </span><span class="k">values</span><span class="w"> </span><span class="o">|</span><span class="w"> </span><span class="k">insert</span><span class="w"> </span><span class="o">|</span><span class="w"> </span><span class="k">update</span><span class="w"> </span><span class="o">|</span><span class="w"> </span><span class="k">delete</span><span class="err">}</span><span class="w"> </span><span class="p">)</span>
|
|
</pre></div></td></tr></table></div>
|
|
|
|
</div>
|
|
<div class="caution" id="EN-US_TOPIC_0000001637921145__en-us_topic_0000001637281285_note5596155185710"><span class="cautiontitle"><img src="public_sys-resources/caution_3.0-en-us.png"> </span><div class="cautionbody"><ul id="EN-US_TOPIC_0000001637921145__en-us_topic_0000001637281285_ul332166574"><li id="EN-US_TOPIC_0000001637921145__en-us_topic_0000001637281285_li332126105712">The SQL statement specified by the AS statement of a CTE must be a statement that can return query results. It can be a common <strong id="EN-US_TOPIC_0000001637921145__b1912948111611">SELECT</strong> query statement or other data modification statements such as <strong id="EN-US_TOPIC_0000001637921145__b2513135401617">INSERT</strong>, <strong id="EN-US_TOPIC_0000001637921145__b9898598167">UPDATE</strong>, <strong id="EN-US_TOPIC_0000001637921145__b17141647173">DELETE</strong>, and <strong id="EN-US_TOPIC_0000001637921145__b2099347131713">VALUES</strong>. When using a data modification statement, you need to use the <strong id="EN-US_TOPIC_0000001637921145__b16607114931714">RETURNING</strong> clause to return tuples. Example:<div class="codecoloring" codetype="Sql" id="EN-US_TOPIC_0000001637921145__en-us_topic_0000001637281285_screen13321068575"><div class="highlight"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre><span class="normal">1</span></pre></div></td><td class="code"><div><pre><span></span><span class="k">WITH</span><span class="w"> </span><span class="n">s</span><span class="w"> </span><span class="k">AS</span><span class="w"> </span><span class="p">(</span><span class="k">INSERT</span><span class="w"> </span><span class="k">INTO</span><span class="w"> </span><span class="n">t</span><span class="w"> </span><span class="k">VALUES</span><span class="p">(</span><span class="mi">1</span><span class="p">)</span><span class="w"> </span><span class="n">RETURNING</span><span class="w"> </span><span class="n">a</span><span class="p">)</span><span class="w"> </span><span class="k">SELECT</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="k">FROM</span><span class="w"> </span><span class="n">s</span><span class="p">;</span>
|
|
</pre></div></td></tr></table></div>
|
|
|
|
</div>
|
|
</li></ul>
|
|
<ul id="EN-US_TOPIC_0000001637921145__en-us_topic_0000001637281285_ul232206175720"><li id="EN-US_TOPIC_0000001637921145__en-us_topic_0000001637281285_li10322616575">A <strong id="EN-US_TOPIC_0000001637921145__b399915512185">WITH</strong> expression indicates the CTE definition in a SQL statement block. Multiple CTEs can be defined at the same time. You can specify column names for each CTE or use the aliases of the columns in the query output. Example:<div class="codecoloring" codetype="Sql" id="EN-US_TOPIC_0000001637921145__en-us_topic_0000001637281285_screen19321805115"><div class="highlight"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre><span class="normal">1</span></pre></div></td><td class="code"><div><pre><span></span><span class="k">WITH</span><span class="w"> </span><span class="n">s1</span><span class="p">(</span><span class="n">a</span><span class="p">,</span><span class="w"> </span><span class="n">b</span><span class="p">)</span><span class="w"> </span><span class="k">AS</span><span class="w"> </span><span class="p">(</span><span class="k">SELECT</span><span class="w"> </span><span class="n">x</span><span class="p">,</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="k">FROM</span><span class="w"> </span><span class="n">t1</span><span class="p">),</span><span class="w"> </span><span class="n">s2</span><span class="w"> </span><span class="k">AS</span><span class="w"> </span><span class="p">(</span><span class="k">SELECT</span><span class="w"> </span><span class="n">x</span><span class="p">,</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="k">FROM</span><span class="w"> </span><span class="n">t2</span><span class="p">)</span><span class="w"> </span><span class="k">SELECT</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="k">FROM</span><span class="w"> </span><span class="n">s1</span><span class="w"> </span><span class="k">JOIN</span><span class="w"> </span><span class="n">s2</span><span class="w"> </span><span class="k">ON</span><span class="w"> </span><span class="n">s1</span><span class="p">.</span><span class="n">a</span><span class="o">=</span><span class="n">s2</span><span class="p">.</span><span class="n">x</span><span class="p">;</span>
|
|
</pre></div></td></tr></table></div>
|
|
|
|
</div>
|
|
<p id="EN-US_TOPIC_0000001637921145__en-us_topic_0000001637281285_p111251314115">This statement defines two CTEs: <strong id="EN-US_TOPIC_0000001637921145__b1394082022612">s1</strong> and <strong id="EN-US_TOPIC_0000001637921145__b1850252412268">s2</strong>. <strong id="EN-US_TOPIC_0000001637921145__b14556112815269">s1</strong> specifies the column names <strong id="EN-US_TOPIC_0000001637921145__b185741733102611">a</strong> and <strong id="EN-US_TOPIC_0000001637921145__b13972123822613">b</strong>, and <strong id="EN-US_TOPIC_0000001637921145__b95231042162613">s2</strong> does not specify the column names. Therefore, the column names are the output column names <strong id="EN-US_TOPIC_0000001637921145__b171882580305">x</strong> and <strong id="EN-US_TOPIC_0000001637921145__b13568170113111">y</strong>.</p>
|
|
</li><li id="EN-US_TOPIC_0000001637921145__en-us_topic_0000001637281285_li43220695714">Each CTE can be referenced zero, one, or more times in the main query.</li><li id="EN-US_TOPIC_0000001637921145__en-us_topic_0000001637281285_li332206125716">CTEs with the same name cannot exist in the same statement block. If CTEs with the same name exist in different statement blocks, the CTE in the nearest statement block is referenced.</li><li id="EN-US_TOPIC_0000001637921145__en-us_topic_0000001637281285_li43212614573">An SQL statement may contain multiple SQL statement blocks. Each statement block can contain a <strong id="EN-US_TOPIC_0000001637921145__b1828185611319">WITH</strong> expression. The CTE in each <strong id="EN-US_TOPIC_0000001637921145__b1054210535311">WITH</strong> expression can be referenced in the current statement block, subsequent CTEs of the current statement block, and sub-layer statement blocks, however, it cannot be referenced in the parent statement block. The definition of each CTE is also a statement block. Therefore, a WITH expression can also be defined in the statement block.</li></ul>
|
|
</div></div>
|
|
<p id="EN-US_TOPIC_0000001637921145__en-us_topic_0000001637281285_p14991064185">The purpose of SELECT in WITH is to break down complex queries into simple parts. Example:</p>
|
|
<div class="codecoloring" codetype="Sql" id="EN-US_TOPIC_0000001637921145__en-us_topic_0000001637281285_screen144991766185"><div class="highlight"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre><span class="normal"> 1</span>
|
|
<span class="normal"> 2</span>
|
|
<span class="normal"> 3</span>
|
|
<span class="normal"> 4</span>
|
|
<span class="normal"> 5</span>
|
|
<span class="normal"> 6</span>
|
|
<span class="normal"> 7</span>
|
|
<span class="normal"> 8</span>
|
|
<span class="normal"> 9</span>
|
|
<span class="normal">10</span>
|
|
<span class="normal">11</span>
|
|
<span class="normal">12</span>
|
|
<span class="normal">13</span>
|
|
<span class="normal">14</span>
|
|
<span class="normal">15</span>
|
|
<span class="normal">16</span></pre></div></td><td class="code"><div><pre><span></span><span class="w"> </span><span class="k">WITH</span><span class="w"> </span><span class="n">regional_sales</span><span class="w"> </span><span class="k">AS</span><span class="w"> </span><span class="p">(</span>
|
|
<span class="w"> </span><span class="k">SELECT</span><span class="w"> </span><span class="n">region</span><span class="p">,</span><span class="w"> </span><span class="k">SUM</span><span class="p">(</span><span class="n">amount</span><span class="p">)</span><span class="w"> </span><span class="k">AS</span><span class="w"> </span><span class="n">total_sales</span>
|
|
<span class="w"> </span><span class="k">FROM</span><span class="w"> </span><span class="n">orders</span>
|
|
<span class="w"> </span><span class="k">GROUP</span><span class="w"> </span><span class="k">BY</span><span class="w"> </span><span class="n">region</span>
|
|
<span class="w"> </span><span class="p">),</span><span class="w"> </span><span class="n">top_regions</span><span class="w"> </span><span class="k">AS</span><span class="w"> </span><span class="p">(</span>
|
|
<span class="w"> </span><span class="k">SELECT</span><span class="w"> </span><span class="n">region</span>
|
|
<span class="w"> </span><span class="k">FROM</span><span class="w"> </span><span class="n">regional_sales</span>
|
|
<span class="w"> </span><span class="k">WHERE</span><span class="w"> </span><span class="n">total_sales</span><span class="w"> </span><span class="o">></span><span class="w"> </span><span class="p">(</span><span class="k">SELECT</span><span class="w"> </span><span class="k">SUM</span><span class="p">(</span><span class="n">total_sales</span><span class="p">)</span><span class="o">/</span><span class="mi">10</span><span class="w"> </span><span class="k">FROM</span><span class="w"> </span><span class="n">regional_sales</span><span class="p">)</span>
|
|
<span class="w"> </span><span class="p">)</span>
|
|
<span class="w"> </span><span class="k">SELECT</span><span class="w"> </span><span class="n">region</span><span class="p">,</span>
|
|
<span class="w"> </span><span class="n">product</span><span class="p">,</span>
|
|
<span class="w"> </span><span class="k">SUM</span><span class="p">(</span><span class="n">quantity</span><span class="p">)</span><span class="w"> </span><span class="k">AS</span><span class="w"> </span><span class="n">product_units</span><span class="p">,</span>
|
|
<span class="w"> </span><span class="k">SUM</span><span class="p">(</span><span class="n">amount</span><span class="p">)</span><span class="w"> </span><span class="k">AS</span><span class="w"> </span><span class="n">product_sales</span>
|
|
<span class="w"> </span><span class="k">FROM</span><span class="w"> </span><span class="n">orders</span>
|
|
<span class="w"> </span><span class="k">WHERE</span><span class="w"> </span><span class="n">region</span><span class="w"> </span><span class="k">IN</span><span class="w"> </span><span class="p">(</span><span class="k">SELECT</span><span class="w"> </span><span class="n">region</span><span class="w"> </span><span class="k">FROM</span><span class="w"> </span><span class="n">top_regions</span><span class="p">)</span>
|
|
<span class="w"> </span><span class="k">GROUP</span><span class="w"> </span><span class="k">BY</span><span class="w"> </span><span class="n">region</span><span class="p">,</span><span class="w"> </span><span class="n">product</span><span class="p">;</span>
|
|
</pre></div></td></tr></table></div>
|
|
|
|
</div>
|
|
<p id="EN-US_TOPIC_0000001637921145__en-us_topic_0000001637281285_p144998601813">The <strong id="EN-US_TOPIC_0000001637921145__b07903445717">WITH</strong> clause defines two auxiliary statements: <strong id="EN-US_TOPIC_0000001637921145__b16555174913712">regional_sales</strong> and <strong id="EN-US_TOPIC_0000001637921145__b11551547713">top_regions</strong>. The output of <strong id="EN-US_TOPIC_0000001637921145__b3175487817">regional_sales</strong> is used in <strong id="EN-US_TOPIC_0000001637921145__b209971316819">top_regions</strong>, and the output of<strong id="EN-US_TOPIC_0000001637921145__b1732416188810"> top_regions</strong> is used in the main <strong id="EN-US_TOPIC_0000001637921145__b436253051017">SELECT</strong> query. This example can be written without <strong id="EN-US_TOPIC_0000001637921145__b83293408102">WITH</strong>. In that case, it must be written with a two-layer nested sub-SELECT statement, making the query longer and difficult to maintain.</p>
|
|
</div>
|
|
<div class="section" id="EN-US_TOPIC_0000001637921145__en-us_topic_0000001637281285_section21031929205120"><h4 class="sectiontitle">Recursive WITH Query</h4><p id="EN-US_TOPIC_0000001637921145__en-us_topic_0000001637281285_p181021429145116">By declaring the keyword <strong id="EN-US_TOPIC_0000001637921145__b15328149367">RECURSIVE</strong>, a WITH query can reference its own output.</p>
|
|
<p id="EN-US_TOPIC_0000001637921145__en-us_topic_0000001637281285_p181021329185119">The common form of a recursive WITH query is as follows:</p>
|
|
<div class="codecoloring" codetype="Sql" id="EN-US_TOPIC_0000001637921145__en-us_topic_0000001637281285_screen7102192965115"><div class="highlight"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre><span class="normal">1</span></pre></div></td><td class="code"><div><pre><span></span><span class="n">non_recursive_term</span><span class="w"> </span><span class="k">UNION</span><span class="w"> </span><span class="p">[</span><span class="k">ALL</span><span class="p">]</span><span class="w"> </span><span class="n">recursive_term</span>
|
|
</pre></div></td></tr></table></div>
|
|
|
|
</div>
|
|
<p id="EN-US_TOPIC_0000001637921145__en-us_topic_0000001637281285_p91021929125110"><strong id="EN-US_TOPIC_0000001637921145__b115821128131318">UNION</strong> performs deduplication when merging sets, while <strong id="EN-US_TOPIC_0000001637921145__b1051973611131">UNION ALLL</strong> directly merges result sets without deduplication. Only recursive items can contain references to the output of the query itself.</p>
|
|
<p id="EN-US_TOPIC_0000001637921145__en-us_topic_0000001637281285_p6102192917518">When using recursive WITH, ensure that the recursive item of the query does not return a tuple. Otherwise, the query will loop infinitely.</p>
|
|
<p id="EN-US_TOPIC_0000001637921145__en-us_topic_0000001637281285_p12309164612711">The table <strong id="EN-US_TOPIC_0000001637921145__b1782116231513">tree</strong> is used to store information about all nodes in the following figure.</p>
|
|
<p id="EN-US_TOPIC_0000001637921145__en-us_topic_0000001637281285_p1830525320716"><span><img id="EN-US_TOPIC_0000001637921145__en-us_topic_0000001637281285_image235164383" src="figure/en-us_image_0000001587804470.png"></span></p>
|
|
<p id="EN-US_TOPIC_0000001637921145__en-us_topic_0000001637281285_p943411281524">The table definition statement is as follows:</p>
|
|
<div class="codecoloring" codetype="Sql" id="EN-US_TOPIC_0000001637921145__en-us_topic_0000001637281285_screen1443415288522"><div class="highlight"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre><span class="normal">1</span></pre></div></td><td class="code"><div><pre><span></span><span class="k">CREATE</span><span class="w"> </span><span class="k">TABLE</span><span class="w"> </span><span class="n">tree</span><span class="p">(</span><span class="n">id</span><span class="w"> </span><span class="nb">INT</span><span class="p">,</span><span class="w"> </span><span class="n">parentid</span><span class="w"> </span><span class="nb">INT</span><span class="p">);</span>
|
|
</pre></div></td></tr></table></div>
|
|
|
|
</div>
|
|
<p id="EN-US_TOPIC_0000001637921145__en-us_topic_0000001637281285_p16434202812520">The data in the table is as follows:</p>
|
|
<div class="codecoloring" codetype="Sql" id="EN-US_TOPIC_0000001637921145__en-us_topic_0000001637281285_screen0778172785715"><div class="highlight"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre><span class="normal"> 1</span>
|
|
<span class="normal"> 2</span>
|
|
<span class="normal"> 3</span>
|
|
<span class="normal"> 4</span>
|
|
<span class="normal"> 5</span>
|
|
<span class="normal"> 6</span>
|
|
<span class="normal"> 7</span>
|
|
<span class="normal"> 8</span>
|
|
<span class="normal"> 9</span>
|
|
<span class="normal">10</span>
|
|
<span class="normal">11</span>
|
|
<span class="normal">12</span>
|
|
<span class="normal">13</span>
|
|
<span class="normal">14</span>
|
|
<span class="normal">15</span>
|
|
<span class="normal">16</span>
|
|
<span class="normal">17</span>
|
|
<span class="normal">18</span></pre></div></td><td class="code"><div><pre><span></span><span class="k">INSERT</span><span class="w"> </span><span class="k">INTO</span><span class="w"> </span><span class="n">tree</span><span class="w"> </span><span class="k">VALUES</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span><span class="mi">0</span><span class="p">),(</span><span class="mi">2</span><span class="p">,</span><span class="mi">1</span><span class="p">),(</span><span class="mi">3</span><span class="p">,</span><span class="mi">1</span><span class="p">),(</span><span class="mi">4</span><span class="p">,</span><span class="mi">2</span><span class="p">),(</span><span class="mi">5</span><span class="p">,</span><span class="mi">2</span><span class="p">),(</span><span class="mi">6</span><span class="p">,</span><span class="mi">3</span><span class="p">),(</span><span class="mi">7</span><span class="p">,</span><span class="mi">3</span><span class="p">),(</span><span class="mi">8</span><span class="p">,</span><span class="mi">4</span><span class="p">),(</span><span class="mi">9</span><span class="p">,</span><span class="mi">4</span><span class="p">),(</span><span class="mi">10</span><span class="p">,</span><span class="mi">6</span><span class="p">),(</span><span class="mi">11</span><span class="p">,</span><span class="mi">6</span><span class="p">),(</span><span class="mi">12</span><span class="p">,</span><span class="mi">10</span><span class="p">);</span>
|
|
|
|
<span class="k">SELECT</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="k">FROM</span><span class="w"> </span><span class="n">tree</span><span class="p">;</span>
|
|
<span class="w"> </span><span class="n">id</span><span class="w"> </span><span class="o">|</span><span class="w"> </span><span class="n">parentid</span>
|
|
<span class="c1">----+----------</span>
|
|
<span class="w"> </span><span class="mi">1</span><span class="w"> </span><span class="o">|</span><span class="w"> </span><span class="mi">0</span>
|
|
<span class="w"> </span><span class="mi">2</span><span class="w"> </span><span class="o">|</span><span class="w"> </span><span class="mi">1</span>
|
|
<span class="w"> </span><span class="mi">3</span><span class="w"> </span><span class="o">|</span><span class="w"> </span><span class="mi">1</span>
|
|
<span class="w"> </span><span class="mi">4</span><span class="w"> </span><span class="o">|</span><span class="w"> </span><span class="mi">2</span>
|
|
<span class="w"> </span><span class="mi">5</span><span class="w"> </span><span class="o">|</span><span class="w"> </span><span class="mi">2</span>
|
|
<span class="w"> </span><span class="mi">6</span><span class="w"> </span><span class="o">|</span><span class="w"> </span><span class="mi">3</span>
|
|
<span class="w"> </span><span class="mi">7</span><span class="w"> </span><span class="o">|</span><span class="w"> </span><span class="mi">3</span>
|
|
<span class="w"> </span><span class="mi">8</span><span class="w"> </span><span class="o">|</span><span class="w"> </span><span class="mi">4</span>
|
|
<span class="w"> </span><span class="mi">9</span><span class="w"> </span><span class="o">|</span><span class="w"> </span><span class="mi">4</span>
|
|
<span class="w"> </span><span class="mi">10</span><span class="w"> </span><span class="o">|</span><span class="w"> </span><span class="mi">6</span>
|
|
<span class="w"> </span><span class="mi">11</span><span class="w"> </span><span class="o">|</span><span class="w"> </span><span class="mi">6</span>
|
|
<span class="w"> </span><span class="mi">12</span><span class="w"> </span><span class="o">|</span><span class="w"> </span><span class="mi">10</span>
|
|
<span class="p">(</span><span class="mi">12</span><span class="w"> </span><span class="k">rows</span><span class="p">)</span>
|
|
</pre></div></td></tr></table></div>
|
|
|
|
</div>
|
|
<p id="EN-US_TOPIC_0000001637921145__en-us_topic_0000001637281285_p15906164819565">You can run the following <strong id="EN-US_TOPIC_0000001637921145__b08231214141616">WITH RECURSIVE</strong> statement to return the nodes and hierarchy information of the entire tree starting from node 1 at the top layer:</p>
|
|
<div class="codecoloring" codetype="Sql" id="EN-US_TOPIC_0000001637921145__en-us_topic_0000001637281285_screen290618617133"><div class="highlight"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre><span class="normal"> 1</span>
|
|
<span class="normal"> 2</span>
|
|
<span class="normal"> 3</span>
|
|
<span class="normal"> 4</span>
|
|
<span class="normal"> 5</span>
|
|
<span class="normal"> 6</span>
|
|
<span class="normal"> 7</span>
|
|
<span class="normal"> 8</span>
|
|
<span class="normal"> 9</span>
|
|
<span class="normal">10</span>
|
|
<span class="normal">11</span></pre></div></td><td class="code"><div><pre><span></span><span class="k">WITH</span><span class="w"> </span><span class="k">RECURSIVE</span><span class="w"> </span><span class="n">nodeset</span><span class="w"> </span><span class="k">AS</span>
|
|
<span class="p">(</span>
|
|
<span class="c1">-- recursive initializing query</span>
|
|
<span class="k">SELECT</span><span class="w"> </span><span class="n">id</span><span class="p">,</span><span class="w"> </span><span class="n">parentid</span><span class="p">,</span><span class="w"> </span><span class="mi">1</span><span class="w"> </span><span class="k">AS</span><span class="w"> </span><span class="k">level</span><span class="w"> </span><span class="k">FROM</span><span class="w"> </span><span class="n">tree</span>
|
|
<span class="k">WHERE</span><span class="w"> </span><span class="n">id</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mi">1</span>
|
|
<span class="k">UNION</span><span class="w"> </span><span class="k">ALL</span>
|
|
<span class="c1">-- recursive join query</span>
|
|
<span class="k">SELECT</span><span class="w"> </span><span class="n">tree</span><span class="p">.</span><span class="n">id</span><span class="p">,</span><span class="w"> </span><span class="n">tree</span><span class="p">.</span><span class="n">parentid</span><span class="p">,</span><span class="w"> </span><span class="k">level</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="mi">1</span><span class="w"> </span><span class="k">FROM</span><span class="w"> </span><span class="n">tree</span><span class="p">,</span><span class="w"> </span><span class="n">nodeset</span><span class="w"> </span>
|
|
<span class="k">WHERE</span><span class="w"> </span><span class="n">tree</span><span class="p">.</span><span class="n">parentid</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">nodeset</span><span class="p">.</span><span class="n">id</span><span class="w"> </span>
|
|
<span class="p">)</span>
|
|
<span class="k">SELECT</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="k">FROM</span><span class="w"> </span><span class="n">nodeset</span><span class="w"> </span><span class="k">ORDER</span><span class="w"> </span><span class="k">BY</span><span class="w"> </span><span class="n">id</span><span class="p">;</span>
|
|
</pre></div></td></tr></table></div>
|
|
|
|
</div>
|
|
<p id="EN-US_TOPIC_0000001637921145__en-us_topic_0000001637281285_p51022293513">In the preceding query, a typical <strong id="EN-US_TOPIC_0000001637921145__b63091196171">WITH RECURSIVE</strong> expression contains the CTE of at least one recursive query. The CTE is defined as a <strong id="EN-US_TOPIC_0000001637921145__b1333910313174">UNION ALL</strong> set operation. The first branch is the recursive start query, and the second branch is the recursive join query, the first part is referenced for continuous recursive join. When this statement is executed, the recursive start query is executed once, and the join query is executed several times. The results are added to the start query result set until the results of some join queries are empty.</p>
|
|
<p id="EN-US_TOPIC_0000001637921145__en-us_topic_0000001637281285_p01024291518">The command output is as follows:</p>
|
|
<pre class="screen" id="EN-US_TOPIC_0000001637921145__en-us_topic_0000001637281285_screen4800437161711"> id | parentid | level
|
|
----+----------+-------
|
|
1 | 0 | 1
|
|
2 | 1 | 2
|
|
3 | 1 | 2
|
|
4 | 2 | 3
|
|
5 | 2 | 3
|
|
6 | 3 | 3
|
|
7 | 3 | 3
|
|
8 | 4 | 4
|
|
9 | 4 | 4
|
|
10 | 6 | 4
|
|
11 | 6 | 4
|
|
12 | 10 | 5
|
|
(12 rows)</pre>
|
|
<p id="EN-US_TOPIC_0000001637921145__en-us_topic_0000001637281285_p17106163071714">According to the returned result, the start query result contains the result set whose level is 1. The join query is executed for five times. The result sets whose levels are 2, 3, 4, and 5 are output for the first four times. During the fifth execution, there is no record whose parentid is the same as the output result set ID, that is, there is no redundant child node. Therefore, the query ends.</p>
|
|
<div class="note" id="EN-US_TOPIC_0000001637921145__en-us_topic_0000001637281285_note204591615162017"><img src="public_sys-resources/note_3.0-en-us.png"><span class="notetitle"> </span><div class="notebody"><p id="EN-US_TOPIC_0000001637921145__en-us_topic_0000001637281285_p184591915182010">GaussDB(DWS) supports distributed execution of <strong id="EN-US_TOPIC_0000001637921145__b13946531183411">WITH RECURSIVE</strong> expressions. <strong id="EN-US_TOPIC_0000001637921145__b15409104710316">WITH RECURSIVE</strong> involves cyclic calculation. Therefore, GaussDB(DWS) introduces the <strong id="EN-US_TOPIC_0000001637921145__b1831223273318">max_recursive_times</strong> parameter to control the maximum number of cycles of WITH RECURSIVE. The default value is <strong id="EN-US_TOPIC_0000001637921145__b224513404333">200</strong>. If the number of cycles exceeds <strong id="EN-US_TOPIC_0000001637921145__b6801114363315">200</strong>, an error is reported.</p>
|
|
</div></div>
|
|
</div>
|
|
<div class="section" id="EN-US_TOPIC_0000001637921145__en-us_topic_0000001637281285_section1422732819275"><h4 class="sectiontitle">Data Modification Statements in WITH</h4><p id="EN-US_TOPIC_0000001637921145__en-us_topic_0000001637281285_p230413062717">Use the <strong id="EN-US_TOPIC_0000001637921145__b58621415344">INSERT</strong>, <strong id="EN-US_TOPIC_0000001637921145__b132064143415">UPDATE</strong>, and <strong id="EN-US_TOPIC_0000001637921145__b1499111712340">DELETE</strong> commands in the WITH clause. This allows the user to perform multiple different operations in the same query. The following is an example:</p>
|
|
<div class="codecoloring" codetype="Sql" id="EN-US_TOPIC_0000001637921145__en-us_topic_0000001637281285_screen361718293357"><div class="highlight"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre><span class="normal">1</span>
|
|
<span class="normal">2</span>
|
|
<span class="normal">3</span>
|
|
<span class="normal">4</span>
|
|
<span class="normal">5</span>
|
|
<span class="normal">6</span></pre></div></td><td class="code"><div><pre><span></span><span class="k">WITH</span><span class="w"> </span><span class="n">moved_tree</span><span class="w"> </span><span class="k">AS</span><span class="w"> </span><span class="p">(</span>
|
|
<span class="w"> </span><span class="k">DELETE</span><span class="w"> </span><span class="k">FROM</span><span class="w"> </span><span class="n">tree</span>
|
|
<span class="w"> </span><span class="k">WHERE</span><span class="w"> </span><span class="n">parentid</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mi">4</span><span class="w"> </span>
|
|
<span class="w"> </span><span class="n">RETURNING</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="p">)</span>
|
|
<span class="w"> </span><span class="k">INSERT</span><span class="w"> </span><span class="k">INTO</span><span class="w"> </span><span class="n">tree_log</span>
|
|
<span class="w"> </span><span class="k">SELECT</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="k">FROM</span><span class="w"> </span><span class="n">moved_tree</span><span class="p">;</span>
|
|
</pre></div></td></tr></table></div>
|
|
|
|
</div>
|
|
<p id="EN-US_TOPIC_0000001637921145__en-us_topic_0000001637281285_p12983011538">The preceding query example actually moves rows from <strong id="EN-US_TOPIC_0000001637921145__b1819614239351">tree</strong> to <strong id="EN-US_TOPIC_0000001637921145__b6102131673515">tree_log</strong>. The <strong id="EN-US_TOPIC_0000001637921145__b17594238133717">DELETE</strong> command in the <strong id="EN-US_TOPIC_0000001637921145__b117781541163711">WITH</strong> clause deletes the specified rows from <strong id="EN-US_TOPIC_0000001637921145__b179541822153614">tree</strong>, returns their contents through the <strong id="EN-US_TOPIC_0000001637921145__b7235144518378">RETURNING</strong> clause, and then the main query reads the output and inserts it into <strong id="EN-US_TOPIC_0000001637921145__b109155411376">tree_log</strong>.</p>
|
|
<p id="EN-US_TOPIC_0000001637921145__en-us_topic_0000001637281285_p852317339355">The data modification statement in the <strong id="EN-US_TOPIC_0000001637921145__b1833981517387">WITH</strong> clause must contain the <strong id="EN-US_TOPIC_0000001637921145__b1573565718394">RETURNING</strong> clause, which is used to return the modified content rather than the target table. The RETURNING clause forms a temporary table that can be referenced by the rest of the query. If a data modification statement in the <strong id="EN-US_TOPIC_0000001637921145__b1773181113435">WITH</strong> statement lacks a <strong id="EN-US_TOPIC_0000001637921145__b106692214313">RETURNING</strong> clause, it cannot form a temporary table and cannot be referenced in the remaining queries.</p>
|
|
<p id="EN-US_TOPIC_0000001637921145__en-us_topic_0000001637281285_p17931367462">If the <strong id="EN-US_TOPIC_0000001637921145__b75884471453">RECURSIVE</strong> keyword is declare, recursive self-reference is not allowed in data modification statements. In some cases, you can bypass this restriction by referencing the output of recursive the <strong id="EN-US_TOPIC_0000001637921145__b14275112018467">WITH</strong> statement. For example:</p>
|
|
<div class="codecoloring" codetype="Sql" id="EN-US_TOPIC_0000001637921145__en-us_topic_0000001637281285_screen105453645214"><div class="highlight"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre><span class="normal">1</span>
|
|
<span class="normal">2</span>
|
|
<span class="normal">3</span>
|
|
<span class="normal">4</span>
|
|
<span class="normal">5</span>
|
|
<span class="normal">6</span>
|
|
<span class="normal">7</span>
|
|
<span class="normal">8</span>
|
|
<span class="normal">9</span></pre></div></td><td class="code"><div><pre><span></span><span class="k">WITH</span><span class="w"> </span><span class="k">RECURSIVE</span><span class="w"> </span><span class="n">included_parts</span><span class="p">(</span><span class="n">sub_part</span><span class="p">,</span><span class="w"> </span><span class="n">part</span><span class="p">)</span><span class="w"> </span><span class="k">AS</span><span class="w"> </span><span class="p">(</span>
|
|
<span class="w"> </span><span class="k">SELECT</span><span class="w"> </span><span class="n">sub_part</span><span class="p">,</span><span class="w"> </span><span class="n">part</span><span class="w"> </span><span class="k">FROM</span><span class="w"> </span><span class="n">parts</span><span class="w"> </span><span class="k">WHERE</span><span class="w"> </span><span class="n">part</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s1">'our_product'</span>
|
|
<span class="w"> </span><span class="k">UNION</span><span class="w"> </span><span class="k">ALL</span>
|
|
<span class="w"> </span><span class="k">SELECT</span><span class="w"> </span><span class="n">p</span><span class="p">.</span><span class="n">sub_part</span><span class="p">,</span><span class="w"> </span><span class="n">p</span><span class="p">.</span><span class="n">part</span>
|
|
<span class="w"> </span><span class="k">FROM</span><span class="w"> </span><span class="n">included_parts</span><span class="w"> </span><span class="n">pr</span><span class="p">,</span><span class="w"> </span><span class="n">parts</span><span class="w"> </span><span class="n">p</span>
|
|
<span class="w"> </span><span class="k">WHERE</span><span class="w"> </span><span class="n">p</span><span class="p">.</span><span class="n">part</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">pr</span><span class="p">.</span><span class="n">sub_part</span>
|
|
<span class="w"> </span><span class="p">)</span><span class="w"> </span>
|
|
<span class="k">DELETE</span><span class="w"> </span><span class="k">FROM</span><span class="w"> </span><span class="n">parts</span>
|
|
<span class="w"> </span><span class="k">WHERE</span><span class="w"> </span><span class="n">part</span><span class="w"> </span><span class="k">IN</span><span class="w"> </span><span class="p">(</span><span class="k">SELECT</span><span class="w"> </span><span class="n">part</span><span class="w"> </span><span class="k">FROM</span><span class="w"> </span><span class="n">included_parts</span><span class="p">);</span>
|
|
</pre></div></td></tr></table></div>
|
|
|
|
</div>
|
|
<p id="EN-US_TOPIC_0000001637921145__en-us_topic_0000001637281285_p125593617524">This query will remove all direct or indirect subparts of a product.</p>
|
|
<p id="EN-US_TOPIC_0000001637921145__en-us_topic_0000001637281285_p1486410385412">The substatements in the <strong id="EN-US_TOPIC_0000001637921145__b122716144716">WITH</strong> clause are executed at the same time as the main query. Therefore, when using the data modification statement in a WITH statement, the actual update order is in an unpredictable manner. All statements are executed in the same snapshot, and the effect of the statements is invisible on the target table. This mitigates the unpredictability of the actual order of row updates and means that <strong id="EN-US_TOPIC_0000001637921145__b16129171712516">RETURNING</strong> data is the only way to convey changes between different <strong id="EN-US_TOPIC_0000001637921145__b1978133615112">WITH</strong> substatements and the main query.</p>
|
|
<p id="EN-US_TOPIC_0000001637921145__en-us_topic_0000001637281285_p14885141925819">In this example, the outer layer <strong id="EN-US_TOPIC_0000001637921145__b6591105220516">SELECT</strong> can return the data before the update.</p>
|
|
<div class="codecoloring" codetype="Sql" id="EN-US_TOPIC_0000001637921145__en-us_topic_0000001637281285_screen1988510191584"><div class="highlight"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre><span class="normal">1</span>
|
|
<span class="normal">2</span>
|
|
<span class="normal">3</span>
|
|
<span class="normal">4</span></pre></div></td><td class="code"><div><pre><span></span><span class="k">WITH</span><span class="w"> </span><span class="n">t</span><span class="w"> </span><span class="k">AS</span><span class="w"> </span><span class="p">(</span>
|
|
<span class="w"> </span><span class="k">UPDATE</span><span class="w"> </span><span class="n">tree</span><span class="w"> </span><span class="k">SET</span><span class="w"> </span><span class="n">id</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">id</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="mi">1</span>
|
|
<span class="w"> </span><span class="n">RETURNING</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="p">)</span><span class="w"> </span>
|
|
<span class="k">SELECT</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="k">FROM</span><span class="w"> </span><span class="n">tree</span><span class="p">;</span>
|
|
</pre></div></td></tr></table></div>
|
|
|
|
</div>
|
|
<p id="EN-US_TOPIC_0000001637921145__en-us_topic_0000001637281285_p188501912585">In this example, the external SELECT returns the updated data.</p>
|
|
<div class="codecoloring" codetype="Sql" id="EN-US_TOPIC_0000001637921145__en-us_topic_0000001637281285_screen988511913589"><div class="highlight"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre><span class="normal">1</span>
|
|
<span class="normal">2</span>
|
|
<span class="normal">3</span>
|
|
<span class="normal">4</span></pre></div></td><td class="code"><div><pre><span></span><span class="k">WITH</span><span class="w"> </span><span class="n">t</span><span class="w"> </span><span class="k">AS</span><span class="w"> </span><span class="p">(</span><span class="w"> </span>
|
|
<span class="k">UPDATE</span><span class="w"> </span><span class="n">tree</span><span class="w"> </span><span class="k">SET</span><span class="w"> </span><span class="n">id</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">id</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="mi">1</span>
|
|
<span class="w"> </span><span class="n">RETURNING</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="p">)</span>
|
|
<span class="k">SELECT</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="k">FROM</span><span class="w"> </span><span class="n">t</span><span class="p">;</span>
|
|
</pre></div></td></tr></table></div>
|
|
|
|
</div>
|
|
<p id="EN-US_TOPIC_0000001637921145__en-us_topic_0000001637281285_p128854194588">The same row cannot be updated twice in a single statement. Otherwise, the update effect will be unpredictable. If only one update takes effect, it is difficult (and sometimes impossible) to predict which one takes effect.</p>
|
|
</div>
|
|
</div>
|
|
<div>
|
|
<div class="familylinks">
|
|
<div class="parentlink"><strong>Parent topic:</strong> <a href="dws_04_1001.html">Data Read</a></div>
|
|
</div>
|
|
</div>
|
|
|