1 <?xml version="1.0" encoding="UTF-8" standalone="no"?>
2 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>7.8. WITH Queries (Common Table Expressions)</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="queries-values.html" title="7.7. VALUES Lists" /><link rel="next" href="datatype.html" title="Chapter 8. Data Types" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">7.8. <code class="literal">WITH</code> Queries (Common Table Expressions)</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="queries-values.html" title="7.7. VALUES Lists">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="queries.html" title="Chapter 7. Queries">Up</a></td><th width="60%" align="center">Chapter 7. Queries</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 18.0 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="datatype.html" title="Chapter 8. Data Types">Next</a></td></tr></table><hr /></div><div class="sect1" id="QUERIES-WITH"><div class="titlepage"><div><div><h2 class="title" style="clear: both">7.8. <code class="literal">WITH</code> Queries (Common Table Expressions) <a href="#QUERIES-WITH" class="id_link">#</a></h2></div></div></div><div class="toc"><dl class="toc"><dt><span class="sect2"><a href="queries-with.html#QUERIES-WITH-SELECT">7.8.1. <code class="command">SELECT</code> in <code class="literal">WITH</code></a></span></dt><dt><span class="sect2"><a href="queries-with.html#QUERIES-WITH-RECURSIVE">7.8.2. Recursive Queries</a></span></dt><dt><span class="sect2"><a href="queries-with.html#QUERIES-WITH-CTE-MATERIALIZATION">7.8.3. Common Table Expression Materialization</a></span></dt><dt><span class="sect2"><a href="queries-with.html#QUERIES-WITH-MODIFYING">7.8.4. Data-Modifying Statements in <code class="literal">WITH</code></a></span></dt></dl></div><a id="id-1.5.6.12.2" class="indexterm"></a><a id="id-1.5.6.12.3" class="indexterm"></a><p>
3 <code class="literal">WITH</code> provides a way to write auxiliary statements for use in a
4 larger query. These statements, which are often referred to as Common
5 Table Expressions or <acronym class="acronym">CTE</acronym>s, can be thought of as defining
6 temporary tables that exist just for one query. Each auxiliary statement
7 in a <code class="literal">WITH</code> clause can be a <code class="command">SELECT</code>,
8 <code class="command">INSERT</code>, <code class="command">UPDATE</code>, <code class="command">DELETE</code>,
9 or <code class="command">MERGE</code>; and the
10 <code class="literal">WITH</code> clause itself is attached to a primary statement that can
11 also be a <code class="command">SELECT</code>, <code class="command">INSERT</code>, <code class="command">UPDATE</code>,
12 <code class="command">DELETE</code>, or <code class="command">MERGE</code>.
13 </p><div class="sect2" id="QUERIES-WITH-SELECT"><div class="titlepage"><div><div><h3 class="title">7.8.1. <code class="command">SELECT</code> in <code class="literal">WITH</code> <a href="#QUERIES-WITH-SELECT" class="id_link">#</a></h3></div></div></div><p>
14 The basic value of <code class="command">SELECT</code> in <code class="literal">WITH</code> is to
15 break down complicated queries into simpler parts. An example is:
17 </p><pre class="programlisting">
18 WITH regional_sales AS (
19 SELECT region, SUM(amount) AS total_sales
25 WHERE total_sales > (SELECT SUM(total_sales)/10 FROM regional_sales)
29 SUM(quantity) AS product_units,
30 SUM(amount) AS product_sales
32 WHERE region IN (SELECT region FROM top_regions)
33 GROUP BY region, product;
36 which displays per-product sales totals in only the top sales regions.
37 The <code class="literal">WITH</code> clause defines two auxiliary statements named
38 <code class="structname">regional_sales</code> and <code class="structname">top_regions</code>,
39 where the output of <code class="structname">regional_sales</code> is used in
40 <code class="structname">top_regions</code> and the output of <code class="structname">top_regions</code>
41 is used in the primary <code class="command">SELECT</code> query.
42 This example could have been written without <code class="literal">WITH</code>,
43 but we'd have needed two levels of nested sub-<code class="command">SELECT</code>s. It's a bit
44 easier to follow this way.
45 </p></div><div class="sect2" id="QUERIES-WITH-RECURSIVE"><div class="titlepage"><div><div><h3 class="title">7.8.2. Recursive Queries <a href="#QUERIES-WITH-RECURSIVE" class="id_link">#</a></h3></div></div></div><p>
46 <a id="id-1.5.6.12.6.2.1" class="indexterm"></a>
47 The optional <code class="literal">RECURSIVE</code> modifier changes <code class="literal">WITH</code>
48 from a mere syntactic convenience into a feature that accomplishes
49 things not otherwise possible in standard SQL. Using
50 <code class="literal">RECURSIVE</code>, a <code class="literal">WITH</code> query can refer to its own
51 output. A very simple example is this query to sum the integers from 1
54 </p><pre class="programlisting">
55 WITH RECURSIVE t(n) AS (
58 SELECT n+1 FROM t WHERE n < 100
63 The general form of a recursive <code class="literal">WITH</code> query is always a
64 <em class="firstterm">non-recursive term</em>, then <code class="literal">UNION</code> (or
65 <code class="literal">UNION ALL</code>), then a
66 <em class="firstterm">recursive term</em>, where only the recursive term can contain
67 a reference to the query's own output. Such a query is executed as
69 </p><div class="procedure" id="id-1.5.6.12.6.3"><p class="title"><strong>Recursive Query Evaluation</strong></p><ol class="procedure" type="1"><li class="step"><p>
70 Evaluate the non-recursive term. For <code class="literal">UNION</code> (but not
71 <code class="literal">UNION ALL</code>), discard duplicate rows. Include all remaining
72 rows in the result of the recursive query, and also place them in a
73 temporary <em class="firstterm">working table</em>.
74 </p></li><li class="step"><p>
75 So long as the working table is not empty, repeat these steps:
76 </p><ol type="a" class="substeps"><li class="step"><p>
77 Evaluate the recursive term, substituting the current contents of
78 the working table for the recursive self-reference.
79 For <code class="literal">UNION</code> (but not <code class="literal">UNION ALL</code>), discard
80 duplicate rows and rows that duplicate any previous result row.
81 Include all remaining rows in the result of the recursive query, and
82 also place them in a temporary <em class="firstterm">intermediate table</em>.
83 </p></li><li class="step"><p>
84 Replace the contents of the working table with the contents of the
85 intermediate table, then empty the intermediate table.
86 </p></li></ol></li></ol></div><div class="note"><h3 class="title">Note</h3><p>
87 While <code class="literal">RECURSIVE</code> allows queries to be specified
88 recursively, internally such queries are evaluated iteratively.
90 In the example above, the working table has just a single row in each step,
91 and it takes on the values from 1 through 100 in successive steps. In
92 the 100th step, there is no output because of the <code class="literal">WHERE</code>
93 clause, and so the query terminates.
95 Recursive queries are typically used to deal with hierarchical or
96 tree-structured data. A useful example is this query to find all the
97 direct and indirect sub-parts of a product, given only a table that
98 shows immediate inclusions:
100 </p><pre class="programlisting">
101 WITH RECURSIVE included_parts(sub_part, part, quantity) AS (
102 SELECT sub_part, part, quantity FROM parts WHERE part = 'our_product'
104 SELECT p.sub_part, p.part, p.quantity * pr.quantity
105 FROM included_parts pr, parts p
106 WHERE p.part = pr.sub_part
108 SELECT sub_part, SUM(quantity) as total_quantity
112 </p><div class="sect3" id="QUERIES-WITH-SEARCH"><div class="titlepage"><div><div><h4 class="title">7.8.2.1. Search Order <a href="#QUERIES-WITH-SEARCH" class="id_link">#</a></h4></div></div></div><p>
113 When computing a tree traversal using a recursive query, you might want to
114 order the results in either depth-first or breadth-first order. This can
115 be done by computing an ordering column alongside the other data columns
116 and using that to sort the results at the end. Note that this does not
117 actually control in which order the query evaluation visits the rows; that
118 is as always in SQL implementation-dependent. This approach merely
119 provides a convenient way to order the results afterwards.
121 To create a depth-first order, we compute for each result row an array of
122 rows that we have visited so far. For example, consider the following
123 query that searches a table <code class="structname">tree</code> using a
124 <code class="structfield">link</code> field:
126 </p><pre class="programlisting">
127 WITH RECURSIVE search_tree(id, link, data) AS (
128 SELECT t.id, t.link, t.data
131 SELECT t.id, t.link, t.data
132 FROM tree t, search_tree st
135 SELECT * FROM search_tree;
138 To add depth-first ordering information, you can write this:
140 </p><pre class="programlisting">
141 WITH RECURSIVE search_tree(id, link, data, <span class="emphasis"><strong>path</strong></span>) AS (
142 SELECT t.id, t.link, t.data, <span class="emphasis"><strong>ARRAY[t.id]</strong></span>
145 SELECT t.id, t.link, t.data, <span class="emphasis"><strong>path || t.id</strong></span>
146 FROM tree t, search_tree st
149 SELECT * FROM search_tree <span class="emphasis"><strong>ORDER BY path</strong></span>;
152 In the general case where more than one field needs to be used to identify
153 a row, use an array of rows. For example, if we needed to track fields
154 <code class="structfield">f1</code> and <code class="structfield">f2</code>:
156 </p><pre class="programlisting">
157 WITH RECURSIVE search_tree(id, link, data, <span class="emphasis"><strong>path</strong></span>) AS (
158 SELECT t.id, t.link, t.data, <span class="emphasis"><strong>ARRAY[ROW(t.f1, t.f2)]</strong></span>
161 SELECT t.id, t.link, t.data, <span class="emphasis"><strong>path || ROW(t.f1, t.f2)</strong></span>
162 FROM tree t, search_tree st
165 SELECT * FROM search_tree <span class="emphasis"><strong>ORDER BY path</strong></span>;
167 </p><div class="tip"><h3 class="title">Tip</h3><p>
168 Omit the <code class="literal">ROW()</code> syntax in the common case where only one
169 field needs to be tracked. This allows a simple array rather than a
170 composite-type array to be used, gaining efficiency.
172 To create a breadth-first order, you can add a column that tracks the depth
173 of the search, for example:
175 </p><pre class="programlisting">
176 WITH RECURSIVE search_tree(id, link, data, <span class="emphasis"><strong>depth</strong></span>) AS (
177 SELECT t.id, t.link, t.data, <span class="emphasis"><strong>0</strong></span>
180 SELECT t.id, t.link, t.data, <span class="emphasis"><strong>depth + 1</strong></span>
181 FROM tree t, search_tree st
184 SELECT * FROM search_tree <span class="emphasis"><strong>ORDER BY depth</strong></span>;
187 To get a stable sort, add data columns as secondary sorting columns.
188 </p><div class="tip"><h3 class="title">Tip</h3><p>
189 The recursive query evaluation algorithm produces its output in
190 breadth-first search order. However, this is an implementation detail and
191 it is perhaps unsound to rely on it. The order of the rows within each
192 level is certainly undefined, so some explicit ordering might be desired
195 There is built-in syntax to compute a depth- or breadth-first sort column.
198 </p><pre class="programlisting">
199 WITH RECURSIVE search_tree(id, link, data) AS (
200 SELECT t.id, t.link, t.data
203 SELECT t.id, t.link, t.data
204 FROM tree t, search_tree st
206 ) <span class="emphasis"><strong>SEARCH DEPTH FIRST BY id SET ordercol</strong></span>
207 SELECT * FROM search_tree ORDER BY ordercol;
209 WITH RECURSIVE search_tree(id, link, data) AS (
210 SELECT t.id, t.link, t.data
213 SELECT t.id, t.link, t.data
214 FROM tree t, search_tree st
216 ) <span class="emphasis"><strong>SEARCH BREADTH FIRST BY id SET ordercol</strong></span>
217 SELECT * FROM search_tree ORDER BY ordercol;
219 This syntax is internally expanded to something similar to the above
220 hand-written forms. The <code class="literal">SEARCH</code> clause specifies whether
221 depth- or breadth first search is wanted, the list of columns to track for
222 sorting, and a column name that will contain the result data that can be
223 used for sorting. That column will implicitly be added to the output rows
225 </p></div><div class="sect3" id="QUERIES-WITH-CYCLE"><div class="titlepage"><div><div><h4 class="title">7.8.2.2. Cycle Detection <a href="#QUERIES-WITH-CYCLE" class="id_link">#</a></h4></div></div></div><p>
226 When working with recursive queries it is important to be sure that
227 the recursive part of the query will eventually return no tuples,
228 or else the query will loop indefinitely. Sometimes, using
229 <code class="literal">UNION</code> instead of <code class="literal">UNION ALL</code> can accomplish this
230 by discarding rows that duplicate previous output rows. However, often a
231 cycle does not involve output rows that are completely duplicate: it may be
232 necessary to check just one or a few fields to see if the same point has
233 been reached before. The standard method for handling such situations is
234 to compute an array of the already-visited values. For example, consider again
235 the following query that searches a table <code class="structname">graph</code> using a
236 <code class="structfield">link</code> field:
238 </p><pre class="programlisting">
239 WITH RECURSIVE search_graph(id, link, data, depth) AS (
240 SELECT g.id, g.link, g.data, 0
243 SELECT g.id, g.link, g.data, sg.depth + 1
244 FROM graph g, search_graph sg
247 SELECT * FROM search_graph;
250 This query will loop if the <code class="structfield">link</code> relationships contain
251 cycles. Because we require a <span class="quote">“<span class="quote">depth</span>”</span> output, just changing
252 <code class="literal">UNION ALL</code> to <code class="literal">UNION</code> would not eliminate the looping.
253 Instead we need to recognize whether we have reached the same row again
254 while following a particular path of links. We add two columns
255 <code class="structfield">is_cycle</code> and <code class="structfield">path</code> to the loop-prone query:
257 </p><pre class="programlisting">
258 WITH RECURSIVE search_graph(id, link, data, depth, <span class="emphasis"><strong>is_cycle, path</strong></span>) AS (
259 SELECT g.id, g.link, g.data, 0,
260 <span class="emphasis"><strong>false,
261 ARRAY[g.id]</strong></span>
264 SELECT g.id, g.link, g.data, sg.depth + 1,
265 <span class="emphasis"><strong>g.id = ANY(path),
266 path || g.id</strong></span>
267 FROM graph g, search_graph sg
268 WHERE g.id = sg.link <span class="emphasis"><strong>AND NOT is_cycle</strong></span>
270 SELECT * FROM search_graph;
273 Aside from preventing cycles, the array value is often useful in its own
274 right as representing the <span class="quote">“<span class="quote">path</span>”</span> taken to reach any particular row.
276 In the general case where more than one field needs to be checked to
277 recognize a cycle, use an array of rows. For example, if we needed to
278 compare fields <code class="structfield">f1</code> and <code class="structfield">f2</code>:
280 </p><pre class="programlisting">
281 WITH RECURSIVE search_graph(id, link, data, depth, <span class="emphasis"><strong>is_cycle, path</strong></span>) AS (
282 SELECT g.id, g.link, g.data, 0,
283 <span class="emphasis"><strong>false,
284 ARRAY[ROW(g.f1, g.f2)]</strong></span>
287 SELECT g.id, g.link, g.data, sg.depth + 1,
288 <span class="emphasis"><strong>ROW(g.f1, g.f2) = ANY(path),
289 path || ROW(g.f1, g.f2)</strong></span>
290 FROM graph g, search_graph sg
291 WHERE g.id = sg.link <span class="emphasis"><strong>AND NOT is_cycle</strong></span>
293 SELECT * FROM search_graph;
295 </p><div class="tip"><h3 class="title">Tip</h3><p>
296 Omit the <code class="literal">ROW()</code> syntax in the common case where only one field
297 needs to be checked to recognize a cycle. This allows a simple array
298 rather than a composite-type array to be used, gaining efficiency.
300 There is built-in syntax to simplify cycle detection. The above query can
301 also be written like this:
302 </p><pre class="programlisting">
303 WITH RECURSIVE search_graph(id, link, data, depth) AS (
304 SELECT g.id, g.link, g.data, 1
307 SELECT g.id, g.link, g.data, sg.depth + 1
308 FROM graph g, search_graph sg
310 ) <span class="emphasis"><strong>CYCLE id SET is_cycle USING path</strong></span>
311 SELECT * FROM search_graph;
313 and it will be internally rewritten to the above form. The
314 <code class="literal">CYCLE</code> clause specifies first the list of columns to
315 track for cycle detection, then a column name that will show whether a
316 cycle has been detected, and finally the name of another column that will track the
317 path. The cycle and path columns will implicitly be added to the output
319 </p><div class="tip"><h3 class="title">Tip</h3><p>
320 The cycle path column is computed in the same way as the depth-first
321 ordering column show in the previous section. A query can have both a
322 <code class="literal">SEARCH</code> and a <code class="literal">CYCLE</code> clause, but a
323 depth-first search specification and a cycle detection specification would
324 create redundant computations, so it's more efficient to just use the
325 <code class="literal">CYCLE</code> clause and order by the path column. If
326 breadth-first ordering is wanted, then specifying both
327 <code class="literal">SEARCH</code> and <code class="literal">CYCLE</code> can be useful.
329 A helpful trick for testing queries
330 when you are not certain if they might loop is to place a <code class="literal">LIMIT</code>
331 in the parent query. For example, this query would loop forever without
332 the <code class="literal">LIMIT</code>:
334 </p><pre class="programlisting">
335 WITH RECURSIVE t(n) AS (
340 SELECT n FROM t <span class="emphasis"><strong>LIMIT 100</strong></span>;
343 This works because <span class="productname">PostgreSQL</span>'s implementation
344 evaluates only as many rows of a <code class="literal">WITH</code> query as are actually
345 fetched by the parent query. Using this trick in production is not
346 recommended, because other systems might work differently. Also, it
347 usually won't work if you make the outer query sort the recursive query's
348 results or join them to some other table, because in such cases the
349 outer query will usually try to fetch all of the <code class="literal">WITH</code> query's
351 </p></div></div><div class="sect2" id="QUERIES-WITH-CTE-MATERIALIZATION"><div class="titlepage"><div><div><h3 class="title">7.8.3. Common Table Expression Materialization <a href="#QUERIES-WITH-CTE-MATERIALIZATION" class="id_link">#</a></h3></div></div></div><p>
352 A useful property of <code class="literal">WITH</code> queries is that they are
353 normally evaluated only once per execution of the parent query, even if
354 they are referred to more than once by the parent query or
355 sibling <code class="literal">WITH</code> queries.
356 Thus, expensive calculations that are needed in multiple places can be
357 placed within a <code class="literal">WITH</code> query to avoid redundant work. Another
358 possible application is to prevent unwanted multiple evaluations of
359 functions with side-effects.
360 However, the other side of this coin is that the optimizer is not able to
361 push restrictions from the parent query down into a multiply-referenced
362 <code class="literal">WITH</code> query, since that might affect all uses of the
363 <code class="literal">WITH</code> query's output when it should affect only one.
364 The multiply-referenced <code class="literal">WITH</code> query will be
365 evaluated as written, without suppression of rows that the parent query
366 might discard afterwards. (But, as mentioned above, evaluation might stop
367 early if the reference(s) to the query demand only a limited number of
370 However, if a <code class="literal">WITH</code> query is non-recursive and
371 side-effect-free (that is, it is a <code class="literal">SELECT</code> containing
372 no volatile functions) then it can be folded into the parent query,
373 allowing joint optimization of the two query levels. By default, this
374 happens if the parent query references the <code class="literal">WITH</code> query
375 just once, but not if it references the <code class="literal">WITH</code> query
376 more than once. You can override that decision by
377 specifying <code class="literal">MATERIALIZED</code> to force separate calculation
378 of the <code class="literal">WITH</code> query, or by specifying <code class="literal">NOT
379 MATERIALIZED</code> to force it to be merged into the parent query.
380 The latter choice risks duplicate computation of
381 the <code class="literal">WITH</code> query, but it can still give a net savings if
382 each usage of the <code class="literal">WITH</code> query needs only a small part
383 of the <code class="literal">WITH</code> query's full output.
385 A simple example of these rules is
386 </p><pre class="programlisting">
388 SELECT * FROM big_table
390 SELECT * FROM w WHERE key = 123;
392 This <code class="literal">WITH</code> query will be folded, producing the same
394 </p><pre class="programlisting">
395 SELECT * FROM big_table WHERE key = 123;
397 In particular, if there's an index on <code class="structfield">key</code>,
398 it will probably be used to fetch just the rows having <code class="literal">key =
399 123</code>. On the other hand, in
400 </p><pre class="programlisting">
402 SELECT * FROM big_table
404 SELECT * FROM w AS w1 JOIN w AS w2 ON w1.key = w2.ref
407 the <code class="literal">WITH</code> query will be materialized, producing a
408 temporary copy of <code class="structname">big_table</code> that is then
409 joined with itself — without benefit of any index. This query
410 will be executed much more efficiently if written as
411 </p><pre class="programlisting">
412 WITH w AS NOT MATERIALIZED (
413 SELECT * FROM big_table
415 SELECT * FROM w AS w1 JOIN w AS w2 ON w1.key = w2.ref
418 so that the parent query's restrictions can be applied directly
419 to scans of <code class="structname">big_table</code>.
421 An example where <code class="literal">NOT MATERIALIZED</code> could be
423 </p><pre class="programlisting">
425 SELECT key, very_expensive_function(val) as f FROM some_table
427 SELECT * FROM w AS w1 JOIN w AS w2 ON w1.f = w2.f;
429 Here, materialization of the <code class="literal">WITH</code> query ensures
430 that <code class="function">very_expensive_function</code> is evaluated only
431 once per table row, not twice.
433 The examples above only show <code class="literal">WITH</code> being used with
434 <code class="command">SELECT</code>, but it can be attached in the same way to
435 <code class="command">INSERT</code>, <code class="command">UPDATE</code>,
436 <code class="command">DELETE</code>, or <code class="command">MERGE</code>.
437 In each case it effectively provides temporary table(s) that can
438 be referred to in the main command.
439 </p></div><div class="sect2" id="QUERIES-WITH-MODIFYING"><div class="titlepage"><div><div><h3 class="title">7.8.4. Data-Modifying Statements in <code class="literal">WITH</code> <a href="#QUERIES-WITH-MODIFYING" class="id_link">#</a></h3></div></div></div><p>
440 You can use data-modifying statements (<code class="command">INSERT</code>,
441 <code class="command">UPDATE</code>, <code class="command">DELETE</code>, or
442 <code class="command">MERGE</code>) in <code class="literal">WITH</code>. This
443 allows you to perform several different operations in the same query.
446 </p><pre class="programlisting">
450 "date" >= '2010-10-01' AND
451 "date" < '2010-11-01'
454 INSERT INTO products_log
455 SELECT * FROM moved_rows;
458 This query effectively moves rows from <code class="structname">products</code> to
459 <code class="structname">products_log</code>. The <code class="command">DELETE</code> in <code class="literal">WITH</code>
460 deletes the specified rows from <code class="structname">products</code>, returning their
461 contents by means of its <code class="literal">RETURNING</code> clause; and then the
462 primary query reads that output and inserts it into
463 <code class="structname">products_log</code>.
465 A fine point of the above example is that the <code class="literal">WITH</code> clause is
466 attached to the <code class="command">INSERT</code>, not the sub-<code class="command">SELECT</code> within
467 the <code class="command">INSERT</code>. This is necessary because data-modifying
468 statements are only allowed in <code class="literal">WITH</code> clauses that are attached
469 to the top-level statement. However, normal <code class="literal">WITH</code> visibility
470 rules apply, so it is possible to refer to the <code class="literal">WITH</code>
471 statement's output from the sub-<code class="command">SELECT</code>.
473 Data-modifying statements in <code class="literal">WITH</code> usually have
474 <code class="literal">RETURNING</code> clauses (see <a class="xref" href="dml-returning.html" title="6.4. Returning Data from Modified Rows">Section 6.4</a>),
475 as shown in the example above.
476 It is the output of the <code class="literal">RETURNING</code> clause, <span class="emphasis"><em>not</em></span> the
477 target table of the data-modifying statement, that forms the temporary
478 table that can be referred to by the rest of the query. If a
479 data-modifying statement in <code class="literal">WITH</code> lacks a <code class="literal">RETURNING</code>
480 clause, then it forms no temporary table and cannot be referred to in
481 the rest of the query. Such a statement will be executed nonetheless.
482 A not-particularly-useful example is:
484 </p><pre class="programlisting">
491 This example would remove all rows from tables <code class="structname">foo</code> and
492 <code class="structname">bar</code>. The number of affected rows reported to the client
493 would only include rows removed from <code class="structname">bar</code>.
495 Recursive self-references in data-modifying statements are not
496 allowed. In some cases it is possible to work around this limitation by
497 referring to the output of a recursive <code class="literal">WITH</code>, for example:
499 </p><pre class="programlisting">
500 WITH RECURSIVE included_parts(sub_part, part) AS (
501 SELECT sub_part, part FROM parts WHERE part = 'our_product'
503 SELECT p.sub_part, p.part
504 FROM included_parts pr, parts p
505 WHERE p.part = pr.sub_part
508 WHERE part IN (SELECT part FROM included_parts);
511 This query would remove all direct and indirect subparts of a product.
513 Data-modifying statements in <code class="literal">WITH</code> are executed exactly once,
514 and always to completion, independently of whether the primary query
515 reads all (or indeed any) of their output. Notice that this is different
516 from the rule for <code class="command">SELECT</code> in <code class="literal">WITH</code>: as stated in the
517 previous section, execution of a <code class="command">SELECT</code> is carried only as far
518 as the primary query demands its output.
520 The sub-statements in <code class="literal">WITH</code> are executed concurrently with
521 each other and with the main query. Therefore, when using data-modifying
522 statements in <code class="literal">WITH</code>, the order in which the specified updates
523 actually happen is unpredictable. All the statements are executed with
524 the same <em class="firstterm">snapshot</em> (see <a class="xref" href="mvcc.html" title="Chapter 13. Concurrency Control">Chapter 13</a>), so they
525 cannot <span class="quote">“<span class="quote">see</span>”</span> one another's effects on the target tables. This
526 alleviates the effects of the unpredictability of the actual order of row
527 updates, and means that <code class="literal">RETURNING</code> data is the only way to
528 communicate changes between different <code class="literal">WITH</code> sub-statements and
529 the main query. An example of this is that in
531 </p><pre class="programlisting">
533 UPDATE products SET price = price * 1.05
536 SELECT * FROM products;
539 the outer <code class="command">SELECT</code> would return the original prices before the
540 action of the <code class="command">UPDATE</code>, while in
542 </p><pre class="programlisting">
544 UPDATE products SET price = price * 1.05
550 the outer <code class="command">SELECT</code> would return the updated data.
552 Trying to update the same row twice in a single statement is not
553 supported. Only one of the modifications takes place, but it is not easy
554 (and sometimes not possible) to reliably predict which one. This also
555 applies to deleting a row that was already updated in the same statement:
556 only the update is performed. Therefore you should generally avoid trying
557 to modify a single row twice in a single statement. In particular avoid
558 writing <code class="literal">WITH</code> sub-statements that could affect the same rows
559 changed by the main statement or a sibling sub-statement. The effects
560 of such a statement will not be predictable.
562 At present, any table used as the target of a data-modifying statement in
563 <code class="literal">WITH</code> must not have a conditional rule, nor an <code class="literal">ALSO</code>
564 rule, nor an <code class="literal">INSTEAD</code> rule that expands to multiple statements.
565 </p></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="queries-values.html" title="7.7. VALUES Lists">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="queries.html" title="Chapter 7. Queries">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="datatype.html" title="Chapter 8. Data Types">Next</a></td></tr><tr><td width="40%" align="left" valign="top">7.7. <code class="literal">VALUES</code> Lists </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 18.0 Documentation">Home</a></td><td width="40%" align="right" valign="top"> Chapter 8. Data Types</td></tr></table></div></body></html>