常规函数
至少有*两种类型的函数 - 常规函数(它们通常称为“函数”)和聚合函数。这是完全不同的概念。常规函数的工作方式是针对每一行单独应用(对于每一行,函数的结果不依赖于其他行)。聚合函数从多个行中累积一组值(即它们依赖于整个行集)。
在本节中,我们讨论常规函数。有关聚合函数,请参见“聚合函数”部分。
强类型
与标准 SQL 相比,ClickHouse 具有强类型。这意味着它不会在类型之间进行隐式转换。每个函数仅适用于特定类型的集合。这意味着有时您需要使用类型转换函数。
通用子表达式消除
查询中所有具有相同 AST(相同记录或相同语法解析结果)的表达式被视为具有相同的值。这些表达式会被串联并执行一次。相同的子查询也会以这种方式被消除。
结果类型
所有函数返回单一值作为结果(不是多个值,也不是零值)。结果的类型通常仅由参数的类型定义,而不是由值定义。例外包括 tupleElement 函数(a.N 操作符)和 toFixedString 函数。
常量
为了简单起见,某些函数只能对某些参数使用常量。例如,LIKE 操作符的右侧参数必须是常量。 几乎所有的函数对于常量参数返回常量。例外是生成随机数的函数。 'now' 函数对于在不同时间运行的查询返回不同的值,但结果被视为常量,因为在单个查询内保持常态是唯一重要的。 常量表达式也被视为常量(例如,LIKE 操作符的右半部分可以由多个常量构成)。
函数对于常量和非常量参数可以以不同的方式实现(执行不同的代码)。但是对于常量和真实列(仅包含相同值的列)的结果应该相匹配。
NULL 处理
函数具有以下行为:
- 如果函数的任一参数为
NULL
,则函数结果也为NULL
。 - 每个函数的描述中单独指定的特殊行为。在 ClickHouse 源代码中,这些函数的
UseDefaultImplementationForNulls=false
。
不变性
函数不能改变其参数的值 - 任何更改都作为结果返回。因此,计算单独函数的结果不依赖于在查询中编写函数的顺序。
高阶函数
->
操作符和 lambda(params, expr) 函数
高阶函数只能接受 lambda 函数作为它们的功能参数。要将 lambda 函数传递给高阶函数,请使用 ->
操作符。箭头的左侧是一个形式参数,可以是任何 ID,或者是多个形式参数 - 在一个元组中的任何 ID。箭头的右侧是一个表达式,可以使用这些形式参数以及任何表列。
示例:
可以将接受多个参数的 lambda 函数传递给高阶函数。在这种情况下,高阶函数将传递多个相同长度的数组,这些参数将与这些数组对应。
对于某些函数,可以省略第一个参数(lambda 函数)。在这种情况下,假设使用相同的映射。
用户自定义函数 (UDFs)
ClickHouse 支持用户自定义函数。请参见 UDFs。