跳至主要内容

条件函数

if

执行条件分支。

如果条件 cond 评估为非零值,则函数返回表达式 then 的结果。如果 cond 评估为零或 NULL,则返回 else 表达式的结果。

设置 short_circuit_function_evaluation 控制是否使用短路评估。如果启用,则仅在 condtrue 的行上评估 then 表达式,而在 condfalse 的行上评估 else 表达式。例如,使用短路评估,在执行查询 SELECT if(number = 0, 0, intDiv(42, number)) FROM numbers(10) 时不会抛出除以零异常。

thenelse 必须是相似的类型。

语法

if(cond, then, else)

别名:cond ? then : else(三元运算符)

参数

  • cond – 评估的条件。UInt8、Nullable(UInt8) 或 NULL。
  • then – 如果 condition 为 true,则返回的表达式。
  • else – 如果 conditionfalse 或 NULL,则返回的表达式。

返回值

根据条件 cond,返回 thenelse 表达式的结果。

示例

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,则函数的结果。

返回值

根据条件 cond_N,返回任何 then_Nelse 表达式的结果。

示例

假设此表

┌─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──────────┐
│ ᴺᵁᴸᴸ │ 4Null value
13left is smaller │
22 │ Both equal │
31left is greater │
4 │ ᴺᵁᴸᴸ │ Null value
└──────┴───────┴─────────────────┘

直接使用条件结果

条件始终返回 01NULL。因此,您可以像这样直接使用条件结果

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 │
13left is smaller │
22 │ Both equal │
31right 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 │
└────────┴─────────┘