diff --git a/content/en/docs/refguide/modeling/domain-model/oql/_index.md b/content/en/docs/refguide/modeling/domain-model/oql/_index.md index 44ad444ff5a..29d89d22b7c 100644 --- a/content/en/docs/refguide/modeling/domain-model/oql/_index.md +++ b/content/en/docs/refguide/modeling/domain-model/oql/_index.md @@ -1,6 +1,7 @@ --- title: "OQL" url: /refguide/oql/ +description: "An introduction to the Mendix Object Query Language with links to further information." weight: 90 --- @@ -37,6 +38,7 @@ OQL is under constant development so some expressions and features are not avail | Feature | Mendix Version | | --- | --- | | Comments | 11.7.0 | +| Parentheses around individual `UNION` subqueries | 11.15.0 | ### [OQL Expressions](/refguide/oql-expression-syntax/) diff --git a/content/en/docs/refguide/modeling/domain-model/oql/oql-clauses.md b/content/en/docs/refguide/modeling/domain-model/oql/oql-clauses.md index da0eae1fdd9..3b3113241fc 100644 --- a/content/en/docs/refguide/modeling/domain-model/oql/oql-clauses.md +++ b/content/en/docs/refguide/modeling/domain-model/oql/oql-clauses.md @@ -1,6 +1,7 @@ --- title: "OQL Clauses" url: /refguide/oql-clauses/ +description: "A reference guide to OQL clauses" weight: 10 aliases: - /refguide/oql-from-clause/ @@ -36,7 +37,7 @@ Clauses must be presented in the following order, but can be left out if they ar 7. [`LIMIT`](#limit-offset) 8. [`OFFSET`](#limit-offset) -The `UNION` clause defies the usual order presented above. It will be presented in a [Union Clause](#oql-union) section at the end. +The `UNION` clause combines multiple SELECT queries and each of these SELECT queries must maintain the order presented above. See [`UNION` Clause](#oql-union), below. The domain model used in the various examples is shown below: @@ -853,7 +854,7 @@ This clause can include items that do not appear in the `SELECT` clause, except {{% alert color="info" %}} The `ORDER BY` clause cannot be used in view entities without a `LIMIT` or an `OFFSET` clause. See [Sorting of View Entity Results](/refguide/use-view-entities/#sorting) in *How To Use View Entities* for more details. -If OQL v2 is enabled, an `ORDER BY` clause cannot be used in subqueries without a `LIMIT` or an `OFFSET` clause because the order of the subquery results may not be retained in the outer query. See the [`ORDER BY` in Subquery](/refguide/oql-v2/#order-by-in-subquery) section of *OQL Version 2 Features* for more details. +If OQL v2 is enabled, an `ORDER BY` clause cannot be used in subqueries without a `LIMIT` or an `OFFSET` clause because the order of the subquery results may not be retained in the outer query. See the [`ORDER BY` in Subqueries](/refguide/oql-v2/#order-by-in-subqueries) section of *OQL Version 2 Features* for more details. {{% /alert %}} ### Syntax @@ -1076,16 +1077,22 @@ All select queries must define the same number of columns in the same order and The syntax is as follows: ```sql - select_query + select_query | ( select_query ) { - UNION [ALL] select_query + UNION [ALL] { select_query | ( select_query ) } } [ ,...n ] [ order_by_clause ] [ LIMIT number ] [ OFFSET number ] ``` -### Result data type {#oql-union-type} +By default, any `order_by_clause`, `LIMIT`, or `OFFSET` in a `UNION` clause will apply to the whole query. Wrapping a select_query in parentheses enables two things. First, it scopes any order_by_clause, LIMIT, or OFFSET inside the parentheses to only that subquery's results. Second, it allows a UNION to be nested inside another UNION, for example, `SELECT query_a UNION (SELECT query_b UNION ALL SELECT query_c)`. The outer UNION can still have its own order_by_clause, LIMIT, and OFFSET applying to the final combined result. See [Parenthesized `UNION` Subqueries](#oql-union-parentheses), below, for an example. + +{{% alert color="info" %}} +Adding parentheses in `UNION` clauses was introduced in Mendix version 11.15.0. It is supported only in Java actions. +{{% /alert %}} + +### Result Data Type {#oql-union-type} The data types used in `select_query` statements are considered when determining the final return type of the `UNION` clause. All data types used in `select_query` statements must be compatible. All data types are compatible with themselves. Differing types are only compatible in these cases: @@ -1196,7 +1203,40 @@ SELECT LastName AS Name FROM Sales.Customer | Doe | | Moose | -#### Union of different types +#### Parenthesized `UNION` Subqueries {#oql-union-parentheses} + +{{% alert color="info" %}} +This feature was introduced in Mendix version 11.15.0. It is supported only in Java actions. +{{% /alert %}} + +You can wrap an individual subquery in parentheses to sort and limit only the results from that subquery rather than the sorting and limiting applying to the result of the `UNION`. This is done by giving each subquery its own `ORDER BY`, `LIMIT` and `OFFSET` clauses. + +For example, the following query uses `UNION` to return the brand and location with the highest and second-lowest stock levels, sorted in ascending order of the amount of stock. + +```sql +( + SELECT Brand, City, Stock + FROM Sales.Location + ORDER BY Stock DESC + LIMIT 1 +) +UNION +( + SELECT Brand, City, Stock + FROM Sales.Location + ORDER BY Stock ASC + LIMIT 1 + OFFSET 1 +) +ORDER BY Stock ASC +``` + +| Brand | City | Stock | +| ------ | ---------- | ----- | +| Veidt | Utrecht | 2 | +| Veidt | Rotterdam | 23 | + +#### Union of Different Types Presume two entities that have columns of types `INTEGER` and `DECIMAL`: @@ -1235,7 +1275,7 @@ SELECT Sale FROM Sales.Sales | 42.25 | | 15.5 | -#### Union of associations +#### Union of Associations Performing a `UNION` with columns that are associations is possible, given the columns refer to the same entity for all select clauses. @@ -1274,6 +1314,10 @@ SELECT Cust.LastName as CustomerName FROM ( A subquery is an OQL query nested inside another query. A subquery can contain the same clauses as a regular OQL query. The entities from the outer query can be referred to in a subquery. A subquery can be used in different parts of the query. +{{% alert color="info" %}} +For the use of subqueries in `UNION` clauses, see [Parenthesized `UNION` Subqueries](#oql-union-parentheses), above. +{{% /alert %}} + ### Subquery in `SELECT` {#subquery-in-select} A subquery can be used as a column in the `SELECT` clause. It can refer to other tables and expressions in `FROM`. diff --git a/content/en/docs/refguide/modeling/domain-model/oql/oql-v2.md b/content/en/docs/refguide/modeling/domain-model/oql/oql-v2.md index 0771917250c..62829cc7ee9 100644 --- a/content/en/docs/refguide/modeling/domain-model/oql/oql-v2.md +++ b/content/en/docs/refguide/modeling/domain-model/oql/oql-v2.md @@ -1,6 +1,7 @@ --- title: "OQL Version 2 Features" linktitle: "Switching to OQL Version 2" +description: "A guide to the differences between Mendix OQL versions 1 and 2, plus a guide to switching to version 2" url: /refguide/oql-v2/ weight: 100 --- @@ -183,7 +184,7 @@ JOIN (SELECT Name AS N FROM Module.City) C ON P/Residence = C/Name ``` -### `ORDER BY` in Subquery {#order-by-in-subquery} +### `ORDER BY` in Subqueries {#order-by-in-subqueries} You must now have a `LIMIT` and/or `OFFSET` in subquery containing `ORDER BY`. Using `ORDER BY` in subquery makes sense only when it is combined with `LIMIT` and/or `OFFSET`. Without the limitations, database engines do not guarantee that the row order in the subquery will be preserved in the outer query. @@ -212,6 +213,22 @@ FROM ( ) ``` +The same restriction applies to a subquery which is a `select_query`, or a nested `UNION` as part of a [`UNION`](/refguide/oql-clauses/#oql-union). Consequently, you can only use `ORDER BY` in a parenthesized `UNION` clause if it is combined with `LIMIT` and/or `OFFSET`: + +```sql +( + SELECT Name + FROM Module.Person + ORDER BY Name + LIMIT 20 +) +UNION +( + SELECT Name + FROM Module.City +) +``` + ### `ORDER BY` in View Entities For [view entities](/refguide/view-entities/), you must now have a `LIMIT` and `OFFSET` in all `ORDER BY` clauses, even for the top level query.