Skip to main content
Skip to main content

条件函数

if

控制条件分支。 与大多数系统不同,ClickHouse始终评估两个表达式 thenelse

语法

SELECT if(cond, then, else)

如果条件 cond 的计算结果为非零值,则返回表达式 then 的结果,并且跳过表达式 else 的结果(如果存在)。 如果 cond 为零或 NULL,则将跳过 then 表达式的结果,并返回 else 表达式的结果(如果存在)。

您可以使用short_circuit_function_evaluation 设置,来根据短路方案计算 if 函数。如果启用此设置,则仅在cond为真的时,加载then表达式,此时不加载else表达式。仅在cond为假时,加载else表达式,此时不加载then表达式。例如,执行查询SELECT if(number = 0, 0, intDiv(42, number)) FROM numbers(10)时不会抛出除以零的异常,因为intDiv(42, number)会仅对不满足条件number = 0的数字进行处理。

参数

  • cond – 条件结果可以为零或不为零。 类型是 UInt8,Nullable(UInt8) 或 NULL。
  • then - 如果满足条件则返回的表达式。
  • else - 如果不满足条件则返回的表达式。

返回值

该函数执行 thenelse 表达式并返回其结果,这取决于条件 cond 最终是否为零。

示例

查询:

SELECT if(1, plus(2, 2), plus(2, 6))

结果:

┌─plus(2, 2)─┐
│ 4 │
└────────────┘

查询:

SELECT if(0, plus(2, 2), plus(2, 6))

结果:

┌─plus(2, 6)─┐
│ 8 │
└────────────┘
  • thenelse 必须具有最低的通用类型。

示例:

给定表LEFT_RIGHT:

SELECT *
FROM LEFT_RIGHT

┌─left─┬─right─┐
│ ᴺᵁᴸᴸ │ 4
13
22
31
4 │ ᴺᵁᴸᴸ │
└──────┴───────┘

下面的查询比较了 leftright 的值:

SELECT
left,
right,
if(left < right, 'left is smaller than right', 'right is smaller or equal than left') AS is_smaller
FROM LEFT_RIGHT
WHERE isNotNull(left) AND isNotNull(right)

┌─left─┬─right─┬─is_smaller──────────────────────────┐
13left is smaller than right
22right is smaller or equal than left
31right is smaller or equal than left
└──────┴───────┴─────────────────────────────────────┘

注意:在此示例中未使用'NULL'值,请检查条件中的NULL值 部分。

三元运算符

if 函数相同。

语法: cond ? then : else

如果cond != 0则返回then,如果cond = 0则返回else

  • cond必须是UInt8类型,thenelse必须存在最低的共同类型。

  • thenelse可以是NULL

参考

multiIf

允许您在查询中更紧凑地编写CASE运算符。

语法

multiIf(cond_1, then_1, cond_2, then_2, ..., else)

您可以使用short_circuit_function_evaluation 设置,根据短路方案计算 multiIf 函数。如果启用此设置,则 then_i 表达式仅在 ((NOT cond_1) AND (NOT cond_2) AND ... AND (NOT cond_{i-1}) AND cond_i) 为真,cond_i 将仅对 ((NOT cond_1) AND (NOT cond_2) AND ... AND (NOT cond_{i-1})) 为真的行进行执行。例如,执行查询“SELECT multiIf(number = 2, intDiv(1, number), number = 5) FROM numbers(10)”时不会抛出除以零的异常。

参数:

  • cond_N — 函数返回then_N的条件。
  • then_N — 执行时函数的结果。
  • else — 如果没有满足任何条件,则为函数的结果。

该函数接受2N + 1参数。

返回值

该函数返回值«then_N»或«else»之一,具体取决于条件cond_N

示例

再次使用表 LEFT_RIGHT

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,你应该仔细构造查询。

以下示例说明这一点。

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 │
└──────┴───────┴──────────────────┘