条件函数
if
执行条件分支。
如果条件 `cond` 的计算结果为非零值,则该函数返回表达式 `then` 的结果。如果 `cond` 的计算结果为零或 `NULL`,则返回 `else` 表达式的结果。
设置 short_circuit_function_evaluation 控制是否使用短路求值。如果启用,则仅在 `cond` 为 `true` 的行上计算 `then` 表达式,而在 `cond` 为 `false` 的行上计算 `else` 表达式。例如,使用短路求值时,执行查询 `SELECT if(number = 0, 0, intDiv(42, number)) FROM numbers(10)` 不会抛出除零异常。
`then` 和 `else` 必须是相似的类型。
语法
if(cond, then, else)
别名:`cond ? then : else` (三元运算符)
参数
- `cond` – 要评估的条件。UInt8、Nullable(UInt8) 或 NULL。
- `then` – 如果 `condition` 为 true,则返回的表达式。
- `else` – 如果 `condition` 为 `false` 或 NULL,则返回的表达式。
返回值
`then` 和 `else` 表达式之一的结果,具体取决于条件 `cond`。
示例
SELECT if(1, plus(2, 2), plus(2, 6));
结果
┌─plus(2, 2)─┐
│ 4 │
└────────────┘
multiIf
允许在查询中更紧凑地编写 CASE 运算符。
语法
multiIf(cond_1, then_1, cond_2, then_2, ..., else)
设置 short_circuit_function_evaluation 控制是否使用短路求值。如果启用,则仅在 `((NOT cond_1) AND (NOT cond_2) AND ... AND (NOT cond_{i-1}) AND cond_i)` 为 `true` 的行上计算 `then_i` 表达式,`cond_i` 将仅在 `((NOT cond_1) AND (NOT cond_2) AND ... AND (NOT cond_{i-1}))` 为 `true` 的行上计算。例如,使用短路求值时,执行查询 `SELECT multiIf(number = 2, intDiv(1, number), number = 5) FROM numbers(10)` 不会抛出除零异常。
参数
该函数接受 `2N+1` 个参数
- `cond_N` — 第 N 个评估条件,用于控制是否返回 `then_N`。
- `then_N` — 当 `cond_N` 为 true 时,函数的返回值。
- `else` — 如果没有条件为 true,则函数的返回值。
返回值
`then_N` 或 `else` 表达式之一的结果,具体取决于条件 `cond_N`。
示例
假设有以下表
┌─left─┬─right─┐
│ ᴺᵁᴸᴸ │ 4 │
│ 1 │ 3 │
│ 2 │ 2 │
│ 3 │ 1 │
│ 4 │ ᴺᵁᴸᴸ │
└──────┴───────┘
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 │
└──────┴───────┴─────────────────┘
直接使用条件结果
条件运算总是返回 `0`、`1` 或 `NULL`。因此,您可以像这样直接使用条件结果
SELECT left < right AS is_small
FROM LEFT_RIGHT
┌─is_small─┐
│ ᴺᵁᴸᴸ │
│ 1 │
│ 0 │
│ 0 │
│ ᴺᵁᴸᴸ │
└──────────┘
条件中的 NULL 值
当 `NULL` 值参与条件运算时,结果也将为 `NULL`。
SELECT
NULL < 1,
2 < NULL,
NULL < NULL,
NULL = NULL
┌─less(NULL, 1)─┬─less(2, NULL)─┬─less(NULL, NULL)─┬─equals(NULL, NULL)─┐
│ ᴺᵁᴸᴸ │ ᴺᵁᴸᴸ │ ᴺᵁᴸᴸ │ ᴺᵁᴸᴸ │
└───────────────┴───────────────┴──────────────────┴────────────────────┘
因此,如果类型为 `Nullable`,您应该仔细构建查询。
以下示例通过未能向 `multiIf` 添加相等条件来演示这一点。
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 │
└──────┴───────┴──────────────────┘
greatest
返回列表中最大的值。列表中的所有成员必须是可比较的类型。
示例
SELECT greatest(1, 2, toUInt8(3), 3.) result, toTypeName(result) type;
┌─result─┬─type────┐
│ 3 │ Float64 │
└────────┴─────────┘
返回的类型是 Float64,因为 UInt8 必须为了比较而提升为 64 位。
SELECT greatest(['hello'], ['there'], ['world'])
┌─greatest(['hello'], ['there'], ['world'])─┐
│ ['world'] │
└───────────────────────────────────────────┘
SELECT greatest(toDateTime32(now() + toIntervalDay(1)), toDateTime64(now(), 3))
┌─greatest(toDateTime32(plus(now(), toIntervalDay(1))), toDateTime64(now(), 3))─┐
│ 2023-05-12 01:16:59.000 │
└──---──────────────────────────────────────────────────────────────────────────┘
返回的类型是 DateTime64,因为 DataTime32 必须为了比较而提升为 64 位。
least
返回列表中最小的值。列表中的所有成员必须是可比较的类型。
示例
SELECT least(1, 2, toUInt8(3), 3.) result, toTypeName(result) type;
┌─result─┬─type────┐
│ 1 │ Float64 │
└────────┴─────────┘
返回的类型是 Float64,因为 UInt8 必须为了比较而提升为 64 位。
SELECT least(['hello'], ['there'], ['world'])
┌─least(['hello'], ['there'], ['world'])─┐
│ ['hello'] │
└────────────────────────────────────────┘
SELECT least(toDateTime32(now() + toIntervalDay(1)), toDateTime64(now(), 3))
┌─least(toDateTime32(plus(now(), toIntervalDay(1))), toDateTime64(now(), 3))─┐
│ 2023-05-12 01:16:59.000 │
└────────────────────────────────────────────────────────────────────────────┘
返回的类型是 DateTime64,因为 DataTime32 必须为了比较而提升为 64 位。
clamp
将返回值约束在 A 和 B 之间。
语法
clamp(value, min, max)
参数
- `value` – 输入值。
- `min` – 限制下限。
- `max` – 限制上限。
返回值
如果值小于最小值,则返回最小值;如果值大于最大值,则返回最大值;否则,返回当前值。
示例
SELECT clamp(1, 2, 3) result, toTypeName(result) type;
┌─result─┬─type────┐
│ 2 │ Float64 │
└────────┴─────────┘