Skip to content

Commit

Permalink
docs: Custom sorting recipe
Browse files Browse the repository at this point in the history
  • Loading branch information
igorlukanin committed Aug 28, 2024
1 parent 1afa934 commit 5632e6b
Show file tree
Hide file tree
Showing 4 changed files with 161 additions and 3 deletions.
1 change: 1 addition & 0 deletions docs/pages/guides/recipes.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ These recipes will show you the best practices of using Cube.
### Queries

- [Getting unique values for a field](/guides/recipes/queries/getting-unique-values-for-a-field)
- [Implementing custom sorting](/guides/recipes/queries/sorting)
- [Implementing pagination](/guides/recipes/queries/pagination)
- [Passing dynamic parameters in a query](/guides/recipes/data-modeling/passing-dynamic-parameters-in-a-query)

Expand Down
5 changes: 3 additions & 2 deletions docs/pages/guides/recipes/queries/_meta.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
module.exports = {
"pagination": "Implementing pagination",
"getting-unique-values-for-a-field": "Getting unique values for a field"
"getting-unique-values-for-a-field": "Getting unique values for a field",
"sorting": "Implementing custom sorting",
"pagination": "Implementing pagination"
}
156 changes: 156 additions & 0 deletions docs/pages/guides/recipes/queries/sorting.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,156 @@
# Implementing custom sorting

In this recipe, you will learn how to sort the result set of a [query][ref-queries]
by your custom criteria.

## Use case

While [data APIs][ref-data-apis] provide built-in ways to sort the result set by
dimensions and measures in ascending or descending order, sometimes you may need
more flexibility.

For example, if a measure or a dimension contains `NULL` values, they will always
appear last last when sorting in the ascending order. This recipe shows how to
work around this behavior for all data APIs.

<ReferenceBox>

Currently, the SQL API does not support `ORDER BY ... NULLS FIRST/LAST`.
Please [track this issue](https://github.com/cube-js/cube/issues/8464).

</ReferenceBox>

## Data modeling

Consider the following data model:

<CodeTabs>

```yaml
cubes:
- name: sort_nulls
sql: >
SELECT 1234 AS value UNION ALL
SELECT 5678 AS value UNION ALL
SELECT NULL AS value
dimensions:
- name: value
sql: value
type: number

- name: value_for_sorting
sql: "COALESCE({value}, 0)"
type: number
```
```javascript
cube(`sort_nulls`, {
sql: `
SELECT 1234 AS value UNION ALL
SELECT 5678 AS value UNION ALL
SELECT NULL AS value
`,

dimensions: {
value: {
sql: `value`,
type: `number`
},

value_for_sorting: {
sql: `COALESCE(${value}, 0)`,
type: `number`
}
}
})
```

</CodeTabs>

You can see that the `value` dimension contains `NULL` values while the
`value_for_sorting` dimension never has `NULL` values. It means that sorting by
the latter dimension will always strictly follow the ascending or descending
order.

Moreover, note that this additional dimension that acts as a *sorting key* may
reference more than one other dimension, allowing to move your complex sorting
logic from the querying layer to your data model.


## Query

Let's query the `value` dimension and sort the result set by that dimension in
the ascending order:

<CodeTabs>

```sql
SELECT value
FROM sort_nulls
GROUP BY 1
ORDER BY 1 ASC;
```

```json
{
"dimensions": [
"sort_nulls.value"
],
"order": {
"sort_nulls.value": "asc"
}
}
```

</CodeTabs>

We'll get the following result set:

| value |
| ------ |
| 1234 |
| 5678 |
| `NULL` |


Now, let's query the `value` dimension but sort the result set by the
`value_for_sorting` dimension in the ascending order:

<CodeTabs>

```sql
SELECT value, value_for_sorting
FROM sort_nulls
GROUP BY 1, 2
ORDER BY 2 ASC;
```

```json
{
"dimensions": [
"sort_nulls.value",
"sort_nulls.value_for_sorting"
],
"order": {
"sort_nulls.value_for_sorting": "asc"
}
}
```

</CodeTabs>

We'll get the following result set:

| value | value_for_sorting |
| ------ | ----------------- |
| `NULL` | 0 |
| 1234 | 1234 |
| 5678 | 5678 |

As you can see, now `NULL` values of the `value` dimension appear first in the
result set.


[ref-queries]: /product/apis-integrations/queries
[ref-data-apis]: /product/apis-integrations#data-apis
2 changes: 1 addition & 1 deletion docs/pages/product/apis-integrations/queries.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ great for most data visualization purposes.
queries by setting `CUBESQL_SQL_NO_IMPLICIT_ORDER` to `true`.

For [REST API][ref-rest-api] and [GraphQL API][ref-graphql-api] queries, you can opt
from default ordering by passing an empty array (`[]`) object as `order`.
out from default ordering by passing an empty array (`[]`) object as `order`.

### Row limit

Expand Down

0 comments on commit 5632e6b

Please sign in to comment.