2017-12-28 15:13:23 +00:00
|
|
|
# Conditional functions
|
|
|
|
|
2020-01-01 16:43:17 +00:00
|
|
|
## `if` function
|
2017-12-28 15:13:23 +00:00
|
|
|
|
2020-01-01 16:43:17 +00:00
|
|
|
Syntax: `if(cond, then, else)`
|
2017-12-28 15:13:23 +00:00
|
|
|
|
2020-01-01 16:43:17 +00:00
|
|
|
Returns `then` if the `cond` is truthy(greater than zero), otherwise returns `else`.
|
2018-09-04 11:18:59 +00:00
|
|
|
|
2020-01-01 16:43:17 +00:00
|
|
|
* `cond` must be of type of `UInt8`, and `then` and `else` must have the lowest common type.
|
2018-09-04 11:18:59 +00:00
|
|
|
|
2020-01-01 16:43:17 +00:00
|
|
|
* `then` and `else` can be `NULL`
|
|
|
|
|
|
|
|
**Example:**
|
|
|
|
|
|
|
|
Take this `LEFT_RIGHT` table:
|
2018-09-04 11:18:59 +00:00
|
|
|
|
2019-09-23 15:31:46 +00:00
|
|
|
```sql
|
2020-01-01 16:43:17 +00:00
|
|
|
SELECT *
|
|
|
|
FROM LEFT_RIGHT
|
|
|
|
|
|
|
|
┌─left─┬─right─┐
|
|
|
|
│ ᴺᵁᴸᴸ │ 4 │
|
|
|
|
│ 1 │ 3 │
|
|
|
|
│ 2 │ 2 │
|
|
|
|
│ 3 │ 1 │
|
|
|
|
│ 4 │ ᴺᵁᴸᴸ │
|
|
|
|
└──────┴───────┘
|
2018-09-04 11:18:59 +00:00
|
|
|
```
|
2020-01-01 16:43:17 +00:00
|
|
|
The following query compares `left` and `right` values:
|
|
|
|
|
|
|
|
```sql
|
|
|
|
SELECT
|
|
|
|
left,
|
|
|
|
right,
|
|
|
|
if(left < right, 'left is smaller than right', 'right is greater or equal than left') AS is_smaller
|
|
|
|
FROM LEFT_RIGHT
|
|
|
|
WHERE isNotNull(left) AND isNotNull(right)
|
|
|
|
|
|
|
|
┌─left─┬─right─┬─is_smaller──────────────────────────┐
|
|
|
|
│ 1 │ 3 │ left is smaller than right │
|
|
|
|
│ 2 │ 2 │ right is greater or equal than left │
|
|
|
|
│ 3 │ 1 │ right is greater or equal than left │
|
|
|
|
└──────┴───────┴─────────────────────────────────────┘
|
|
|
|
```
|
2020-01-04 20:16:43 +00:00
|
|
|
Note: `NULL` values are not used in this example, check [NULL values in conditionals](#null-values-in-conditionals) section.
|
2020-01-01 16:43:17 +00:00
|
|
|
|
|
|
|
## Ternary operator
|
|
|
|
|
|
|
|
It works same as `if` function.
|
|
|
|
|
|
|
|
Syntax: `cond ? then : else`
|
|
|
|
|
|
|
|
Returns `then` if the `cond` is truthy(greater than zero), otherwise returns `else`.
|
|
|
|
|
|
|
|
* `cond` must be of type of `UInt8`, and `then` and `else` must have the lowest common type.
|
|
|
|
|
|
|
|
* `then` and `else` can be `NULL`
|
|
|
|
|
|
|
|
## multiIf
|
|
|
|
|
|
|
|
Allows you to write the [CASE](../operators.md#operator_case) operator more compactly in the query.
|
|
|
|
|
|
|
|
Syntax: `multiIf(cond_1, then_1, cond_2, then_2, ..., else)`
|
2018-09-04 11:18:59 +00:00
|
|
|
|
|
|
|
**Parameters:**
|
|
|
|
|
|
|
|
- `cond_N` — The condition for the function to return `then_N`.
|
|
|
|
- `then_N` — The result of the function when executed.
|
|
|
|
- `else` — The result of the function if none of the conditions is met.
|
|
|
|
|
|
|
|
The function accepts `2N+1` parameters.
|
|
|
|
|
|
|
|
**Returned values**
|
|
|
|
|
|
|
|
The function returns one of the values `then_N` or `else`, depending on the conditions `cond_N`.
|
|
|
|
|
|
|
|
**Example**
|
|
|
|
|
2020-01-01 16:43:17 +00:00
|
|
|
Again using `LEFT_RIGHT` table.
|
|
|
|
|
|
|
|
```sql
|
|
|
|
SELECT
|
|
|
|
left,
|
|
|
|
right,
|
|
|
|
multiIf(left < right, 'left is smaller', left > right, 'left is greater', left = right, 'Both equal', 'Null value') AS result
|
|
|
|
FROM LEFT_RIGHT
|
|
|
|
|
|
|
|
┌─left─┬─right─┬─result──────────┐
|
|
|
|
│ ᴺᵁᴸᴸ │ 4 │ Null value │
|
|
|
|
│ 1 │ 3 │ left is smaller │
|
|
|
|
│ 2 │ 2 │ Both equal │
|
|
|
|
│ 3 │ 1 │ left is greater │
|
|
|
|
│ 4 │ ᴺᵁᴸᴸ │ Null value │
|
|
|
|
└──────┴───────┴─────────────────┘
|
|
|
|
```
|
|
|
|
## Using conditional results directly
|
|
|
|
|
|
|
|
Conditionals always result to `0`, `1` or `NULL`. So you can use conditional results directly like this:
|
|
|
|
|
|
|
|
```sql
|
|
|
|
SELECT left < right AS is_small
|
|
|
|
FROM LEFT_RIGHT
|
|
|
|
|
|
|
|
┌─is_small─┐
|
|
|
|
│ ᴺᵁᴸᴸ │
|
|
|
|
│ 1 │
|
|
|
|
│ 0 │
|
|
|
|
│ 0 │
|
|
|
|
│ ᴺᵁᴸᴸ │
|
|
|
|
└──────────┘
|
|
|
|
```
|
|
|
|
|
|
|
|
|
2020-01-04 20:16:43 +00:00
|
|
|
## NULL values in conditionals
|
2020-01-01 16:43:17 +00:00
|
|
|
|
|
|
|
When `NULL` values are involved in conditionals, the result will also be `NULL`.
|
2018-09-04 11:18:59 +00:00
|
|
|
|
2020-01-01 16:43:17 +00:00
|
|
|
```sql
|
|
|
|
SELECT
|
|
|
|
NULL < 1,
|
|
|
|
2 < NULL,
|
|
|
|
NULL < NULL,
|
|
|
|
NULL = NULL
|
|
|
|
|
|
|
|
┌─less(NULL, 1)─┬─less(2, NULL)─┬─less(NULL, NULL)─┬─equals(NULL, NULL)─┐
|
|
|
|
│ ᴺᵁᴸᴸ │ ᴺᵁᴸᴸ │ ᴺᵁᴸᴸ │ ᴺᵁᴸᴸ │
|
|
|
|
└───────────────┴───────────────┴──────────────────┴────────────────────┘
|
2018-09-04 11:18:59 +00:00
|
|
|
```
|
|
|
|
|
2020-01-01 16:43:17 +00:00
|
|
|
So you should construct your queries carefully if the types are `Nullable`.
|
|
|
|
|
|
|
|
The following example demonstrates this by failing to add equals condition to `multiIf`.
|
2018-09-04 11:18:59 +00:00
|
|
|
|
2020-01-01 16:43:17 +00:00
|
|
|
```sql
|
|
|
|
SELECT
|
|
|
|
left,
|
|
|
|
right,
|
|
|
|
multiIf(left < right, 'left is smaller', left > right, 'right is smaller', 'Both equal') AS faulty_result
|
|
|
|
FROM LEFT_RIGHT
|
|
|
|
|
|
|
|
┌─left─┬─right─┬─faulty_result────┐
|
|
|
|
│ ᴺᵁᴸᴸ │ 4 │ Both equal │
|
|
|
|
│ 1 │ 3 │ left is smaller │
|
|
|
|
│ 2 │ 2 │ Both equal │
|
|
|
|
│ 3 │ 1 │ right is smaller │
|
|
|
|
│ 4 │ ᴺᵁᴸᴸ │ Both equal │
|
|
|
|
└──────┴───────┴──────────────────┘
|
2018-09-04 11:18:59 +00:00
|
|
|
```
|
2018-10-16 10:47:17 +00:00
|
|
|
|
2020-01-01 16:43:17 +00:00
|
|
|
|
2018-10-16 10:47:17 +00:00
|
|
|
[Original article](https://clickhouse.yandex/docs/en/query_language/functions/conditional_functions/) <!--hide-->
|