A common table expression (CTE) is a named temporary result set that exists within the scope of a single statement and that can be referred to later within that statement, possibly multiple times.
1 With
This tag allows you to do WITH ... AS operations independent of the DBMS.
<with recursive='true|false'>
<as
name='name'
params='params'
> +
<select /> *
<union /> *
</as>
</with>
Attributes | |||||
---|---|---|---|---|---|
Name | Type | Required | Default | Description | |
Arecursive | string | false | Indicates whether there is any recursive CTE. |
Arguments | |||||
---|---|---|---|---|---|
Name | Type | Required | Unique | Nullable | Description |
Eas | Defines a new table expression. | ||||
Aname | string | The table expression name. | |||
Aparams | string | Define the CTE column names. If not declared, they are implied by the select. This attribute is necessary for recursive CTEs. | |||
Eselect | Select statement. | ||||
Eunion | Union statement. |
Returns | |
---|---|
Type | Description |
ResultSet | The query result. |
Example
Copy
<with> <as name="cte1"> <select> <columns> a1 </columns> <from table="master_table"/> </select> </as> <select> <columns> a1 </columns> <from table="cte1"/> </select> </with>
2 Multiple CTEs
More than one common table expression can be defined to be used in the following statement (select or union).
Example
Copy
<with> <as name="cte1"> <select> <columns> a1 </columns> <from table="master_table_1"/> </select> </as> <as name="cte2"> <select> <columns> a1 </columns> <from table="master_table_2"/> </select> </as> <select> <columns> cte1.a1 </columns> <from table="cte1"> <join table="cte2"> <on>cte1.a1 = cte2.a1</on> </join> </from> </select> </with>
3 Recursivity
Recursivity can also be used with common table expressions. If there is any recursive CTE, recursive
must be set to true in the with
tag, and the parameters must be set in params
in the corresponding as
tag.
Example
Copy
<with recursive="true"> <as name="cte1" params="n, fact"> <union> <select-one> <columns> 0, 1 </columns> </select-one> <select> <columns> n+1, (n+1)*fact </columns> <from table="cte1"/> <where>n < 9</where> </select> </union> </as> <select> <columns> n, fact </columns> <from table="cte1"/> </select> </with>
4 Multiple and recursive
Multiple CTEs, some of them being recursive, can also be created.
Example
Copy
<with recursive="true"> <as name="cte1" params="n, fact"> <union> <select-one> <columns> 0, 1 </columns> </select-one> <select> <columns> n+1, (n+1)*fact </columns> <from table="cte1"/> <where>n < 9</where> </select> </union> </as> <as name="cte2"> <select> <columns> a1 </columns> <from table="master_table"/> </select> </as> <select> <columns> a1, n, fact </columns> <from table="cte1, cte2"/> </select> </with>
5 Usefulness example
One of the biggest advantages of CTEs is to avoid code duplication, thus making the code more readable. In the following example the repetition of the CASE WHEN
is avoided.
Example
Copy
<with> <as> <select> <column> film_id, title, (CASE WHEN length < 30 THEN 'Short' WHEN length < 90 THEN 'Medium' ELSE 'Long' END) length </column> <from table="film"/> </select> </as> <select> <column> film_id, title, length </column> <from table="cte_film"/> </select> </with>