表达式 API
表达式 API
select 和 filter 等 DataFrame 方法接受一个或多个逻辑表达式,同时还有许多用于创建逻辑表达式的函数可用。这些内容将在下文进行说明。
提示
大多数函数和方法都可以接收并返回一个 Expr,可以使用流式(fluent)风格的 API 将它们串联起来:
use datafusion::prelude::*;
// create the expression `(a > 6) AND (b < 7)`
col("a").gt(lit(6)).and(col("b").lt(lit(7)));标识符
| 语法 | 说明 |
|---|---|
| col(ident) | 引用数据框中的某一列 col("a") |
注意
ident
实现了 Into<Column> trait 的类型
字面量值
| 语法 | 说明 |
|---|---|
| lit(value) | 字面量值,例如 lit(123) 或 lit("hello") |
注意
value
实现了 Literal 的类型
布尔表达式
| 语法 | 说明 |
|---|---|
| and(x, y), x.and(y) | 逻辑与 |
| or(x, y), x.or(y) | 逻辑或 |
| !x, not(x), x.not() | 逻辑非 |
注意
! 在 Rust 中是按位取反或逻辑取反运算符,但在表达式 API 中它只表示逻辑非。
注意
由于 && 和 || 在 Rust 中是逻辑运算符且无法被重载,因此表达式 API 中不提供这两个运算符。
按位表达式
| 语法 | 说明 | |
|---|---|---|
| x & y, bitwise_and(x, y), x.bitand(y) | 与 | |
| x \ | y, bitwise_or(x, y), x.bitor(y) | 或 |
| x ^ y, bitwise_xor(x, y), x.bitxor(y) | 异或 | |
| x << y, bitwise_shift_left(x, y), x.shl(y) | 左移 | |
| x >> y, bitwise_shift_right(x, y), x.shr(y) | 右移 |
比较表达式
| 语法 | 说明 |
|---|---|
| x.eq(y) | 等于 |
| x.not_eq(y) | 不等于 |
| x.gt(y) | 大于 |
| x.gt_eq(y) | 大于等于 |
| x.lt(y) | 小于 |
| x.lt_eq(y) | 小于等于 |
注意
比较运算符(<、<=、==、>=、>)在 Rust 中可以由 PartialOrd 和 PartialEq trait 重载,但这些运算符总是返回 bool,因此无法在表达式 API 中使用。
算术表达式
| 语法 | 说明 |
|---|---|
| x + y, x.add(y) | 加法 |
| x - y, x.sub(y) | 减法 |
| x * y, x.mul(y) | 乘法 |
| x / y, x.div(y) | 除法 |
| x % y, x.rem(y) | 取余 |
| -x, x.neg() | 取负 |
数学函数
| 语法 | 说明 |
|---|---|
| abs(x) | 绝对值 |
| acos(x) | 反余弦 |
| acosh(x) | 反双曲余弦 |
| asin(x) | 反正弦 |
| asinh(x) | 反双曲正弦 |
| atan(x) | 反正切 |
| atanh(x) | 反双曲正切 |
| atan2(y, x) | y / x 的反正切 |
| cbrt(x) | 立方根 |
| ceil(x) | 大于等于参数的最小整数 |
| cos(x) | 余弦 |
| cosh(x) | 双曲余弦 |
| degrees(x) | 将弧度转换为角度 |
| exp(x) | 指数函数 |
| factorial(x) | 阶乘 |
| floor(x) | 小于等于参数的最大整数 |
| gcd(x, y) | 最大公约数 |
| isnan(x) | 判断是否为 NaN/-NaN 的谓词 |
| iszero(x) | 判断是否为 0.0/-0.0 的谓词 |
| lcm(x, y) | 最小公倍数 |
| ln(x) | 自然对数 |
| log(base, x) | 以指定底数求 x 的对数 |
| log10(x) | 以 10 为底的对数 |
| log2(x) | 以 2 为底的对数 |
| nanvl(x, y) | 若 x 不是 NaN 则返回 x,否则返回 y |
| pi() | π 的近似值 |
| power(base, exponent) | base 的 exponent 次幂 |
| radians(x) | 将角度转换为弧度 |
| round(x) | 四舍五入到最近的整数 |
| signum(x) | 参数的符号(-1、0、+1) |
| sin(x) | 正弦 |
| sinh(x) | 双曲正弦 |
| sqrt(x) | 平方根 |
| tan(x) | 正切 |
| tanh(x) | 双曲正切 |
| trunc(x) | 向零截断 |
Note
与某些数据库不同,DataFusion 中的数学函数与 Rust 的数学函数行为一致,避免在边界情况下出错,例如:
select log(-1), log(0), sqrt(-1);
+----------------+---------------+-----------------+
| log(Int64(-1)) | log(Int64(0)) | sqrt(Int64(-1)) |
+----------------+---------------+-----------------+
| NaN | -inf | NaN |
+----------------+---------------+-----------------+条件表达式
语法
说明
coalesce([value, …])
返回参数中第一个非空值。只有当所有参数都为空时才返回空值。它常用于在检索数据进行展示时,用默认值替代空值。
case(expr)
.when(expr)
.end(),
case(expr)
.when(expr)
.otherwise(expr)
CASE 表达式。该表达式可以链式连接多个 when 表达式,并以 end 或 otherwise 表达式结束。示例:
case(col(“a”) % lit(3))
.when(lit(0), lit(“A”))
.when(lit(1), lit(“B”))
.when(lit(2), lit(“C”))
.end()或者以 otherwise 结尾,用于匹配其他所有条件:
case(col(“b”).gt(lit(100)))
.when(lit(true), lit(“value > 100”))
.otherwise(lit(“value <= 100”))nullif(value1, value2)
如果 value1 等于 value2,则返回 null 值;否则返回 value1。它可用于执行 coalesce 表达式的逆操作。
字符串表达式
| 语法 | 说明 |
|---|---|
| ascii(character) | 返回字符(character)的数值表示。示例:ascii('a') -> 97 |
| bit_length(text) | 返回字符串(text)的长度(以位为单位)。示例:bit_length('spider') -> 48 |
| btrim(text, characters) | 从字符串(text)的开头和结尾移除所有指定的字符(characters)。示例:btrim('aabchelloccb', 'abc') -> hello |
| char_length(text) | 返回字符串(text)中的字符数。与 character_length 和 length 相同。示例:char_length('lion') -> 4 |
| character_length(text) | 返回字符串(text)中的字符数。与 char_length 和 length 相同。示例:character_length('lion') -> 4 |
| concat(value1, [value2 [, …]]) | 将所有参数的文本表示(value1, [value2 [, ...]])连接起来。NULL 参数将被忽略。示例:concat('aaa', 'bbc', NULL, 321) -> aaabbc321 |
| concat_ws(separator, value1, [value2 [, …]]) | 使用分隔符(separator)将所有参数的文本表示(value1, [value2 [, ...]])连接起来。NULL 参数将被忽略。concat_ws('/', 'path', 'to', NULL, 'my', 'folder', 123) -> path/to/my/folder/123 |
| chr(integer) | 根据数值表示(integer)返回对应字符。示例:chr(90) -> 8 |
| initcap | 将每个单词的首字母转换为大写,其余字母转换为小写。示例:initcap('hi TOM') -> Hi Tom |
| left(text, number) | 返回字符串(text)开头的指定数量(number)的字符。示例:left('like', 2) -> li |
| length(text) | 返回字符串(text)中的字符数。与 character_length 和 char_length 相同。示例:length('lion') -> 4 |
| lower(text) | 将字符串(text)中的所有字符转换为小写。示例:lower('HELLO') -> hello |
| lpad(text, length, [, fill]) | 通过在前面填充字符(fill)(默认为空格)将字符串扩展到指定长度(length)。示例:lpad('bb', 5, 'a') → aaabb |
| ltrim(text, text) | 从字符串(text)的开头移除所有指定的字符(characters)。示例:ltrim('aabchelloccb', 'abc') -> helloccb |
| md5(text) | 计算参数(text)的 MD5 哈希值。 |
| octet_length(text) | 返回字符串或二进制数据(text)中的字节数。 |
| repeat(text, number) | 将字符串重复指定的次数。示例:repeat('1', 4) -> 1111 |
| replace(string, from, to) | 在字符串(string)中将指定的字符串(from)替换为另一个指定的字符串(to)。示例:replace('Hello', 'replace', 'el') -> Hola |
| reverse(text) | 反转字符串(text)中字符的顺序。示例:reverse('hello') -> olleh |
| right(text, number) | 返回字符串(text)末尾的指定数量(number)的字符。示例:right('like', 2) -> ke |
| rpad(text, length, [, fill]) | 通过在后面填充字符(fill)(默认为空格)将字符串扩展到指定长度(length)。示例:rpad('bb', 5, 'a') → bbaaa |
| rtrim | 从字符串(text)的末尾移除所有指定的字符(characters)。示例:rtrim('aabchelloccb', 'abc') -> aabchello |
| digest(input, algorithm) | 使用 algorithm 计算 input 的二进制哈希值。 |
| split_part(string, delimiter, index) | 根据分隔符(delimiter)拆分字符串(string),并根据索引(index)取出所需的字段。 |
| starts_with(string, prefix) | 如果字符串(string)以指定的前缀(prefix)开头,则返回 true,否则返回 false。示例:starts_with('Hi Tom', 'Hi') -> true |
| strpos | 查找 substring 与 string 匹配的起始位置 |
| substr(string, position, [, length]) | 返回字符串(string)中从位置(position)开始、长度为 length 个字符的子串。 |
| translate(string, from, to) | 将 from 中的字符替换为 to 中对应的字符。示例:translate('abcde', 'acd', '15') -> 1b5e |
| trim(string) | 从字符串(string)中移除所有字符,默认为空格 |
| upper | 将字符串中的所有字符转换为大写。示例:upper('hello') -> HELLO |
数组表达式
| 语法 | 说明 |
|---|---|
| array_any_value(array) | 返回数组中第一个非空元素。array_any_value([NULL, 1, 2, 3]) -> 1 |
| array_append(array, element) | 将元素追加到数组末尾。array_append([1, 2, 3], 4) -> [1, 2, 3, 4] |
| array_concat(array[, …, array_n]) | 连接多个数组。array_concat([1, 2, 3], [4, 5, 6]) -> [1, 2, 3, 4, 5, 6] |
| array_has(array, element) | 如果数组包含该元素则返回 true。array_has([1,2,3], 1) -> true |
| array_has_all(array, sub-array) | 如果子数组的所有元素都存在于数组中则返回 true。array_has_all([1,2,3], [1,3]) -> true |
| array_has_any(array, sub-array) | 如果两个数组中存在相同的元素则返回 true。array_has_any([1,2,3], [1,4]) -> true |
| array_dims(array) | 返回数组各维度组成的数组。array_dims([[1, 2, 3], [4, 5, 6]]) -> [2, 3] |
| array_distinct(array) | 移除重复值后返回数组中的不重复值。array_distinct([1, 3, 2, 3, 1, 2, 4]) -> [1, 2, 3, 4] |
| array_element(array, index) | 提取数组中索引为 n 的元素。array_element([1, 2, 3, 4], 3) -> 3 |
| empty(array) | 如果是空数组则返回 true,如果是非空数组则返回 false。empty([1]) -> false |
| flatten(array) | 将嵌套数组转换为扁平数组。flatten([[1], [2, 3], [4, 5, 6]]) -> [1, 2, 3, 4, 5, 6] |
| array_length(array, dimension) | 返回数组指定维度的长度。array_length([1, 2, 3, 4, 5]) -> 5 |
| array_ndims(array) | 返回数组的维度数。array_ndims([[1, 2, 3], [4, 5, 6]]) -> 2 |
| array_pop_front(array) | 返回移除第一个元素后的数组。array_pop_front([1, 2, 3]) -> [2, 3] |
| array_pop_back(array) | 返回移除最后一个元素后的数组。array_pop_back([1, 2, 3]) -> [1, 2] |
| array_position(array, element) | 在数组中查找该元素,返回首次出现的位置。array_position([1, 2, 2, 3, 4], 2) -> 2 |
| array_positions(array, element) | 在数组中查找该元素,返回所有出现的位置。array_positions([1, 2, 2, 3, 4], 2) -> [2, 3] |
| array_prepend(element, array) | 将元素插入到数组开头。array_prepend(1, [2, 3, 4]) -> [1, 2, 3, 4] |
| array_repeat(element, count) | 返回包含该元素 count 次的数组。array_repeat(1, 3) -> [1, 1, 1] |
| array_remove(array, element) | 从数组中移除第一个与给定值相等的元素。移除非 NULL 值时,数组中已有的 NULL 元素会被保留;array_remove(array, NULL) 返回 NULL。array_remove([1, 2, NULL, 2, 4], 2) -> [1, NULL, 2, 4] |
| array_remove_n(array, element, max) | 从数组中移除前 max 个与给定值相等的元素。移除非 NULL 值时,数组中已有的 NULL 元素会被保留;array_remove_n(array, NULL, max) 返回 NULL。array_remove_n([1, 2, NULL, 2, 4], 2, 2) -> [1, NULL, 4] |
| array_remove_all(array, element) | 移除数组中所有与给定值相等的元素。移除非 NULL 值时,数组中已有的 NULL 元素会被保留;array_remove_all(array, NULL) 返回 NULL。array_remove_all([1, 2, NULL, 2, 4], 2) -> [1, NULL, 4] |
| array_replace(array, from, to) | 将指定元素的首次出现替换为另一个指定元素。array_replace([1, 2, 2, 3, 2, 1, 4], 2, 5) -> [1, 5, 2, 3, 2, 1, 4] |
| array_replace_n(array, from, to, max) | 将指定元素的前 max 次出现替换为另一个指定元素。array_replace_n([1, 2, 2, 3, 2, 1, 4], 2, 5, 2) -> [1, 5, 5, 3, 2, 1, 4] |
| array_replace_all(array, from, to) | 将指定元素的所有出现替换为另一个指定元素。array_replace_all([1, 2, 2, 3, 2, 1, 4], 2, 5) -> [1, 5, 5, 3, 5, 1, 4] |
| array_slice(array, begin,end) | 返回数组的一个切片。array_slice([1, 2, 3, 4, 5, 6, 7, 8], 3, 6) -> [3, 4, 5, 6] |
| array_slice(array, begin, end, stride) | 返回数组的一个切片,并支持步长特性。array_slice([1, 2, 3, 4, 5, 6, 7, 8], 3, 6, 2) -> [3, 5, 6] |
| array_to_string(array, delimiter) | 将每个元素转换为其文本表示。array_to_string([1, 2, 3, 4], ',') -> 1,2,3,4 |
| array_intersect(array1, array2) | 返回 array1 和 array2 交集中的元素组成的数组。array_intersect([1, 2, 3, 4], [5, 6, 3, 4]) -> [3, 4] |
| array_union(array1, array2) | 返回 array1 和 array2 并集中去重后的元素组成的数组。array_union([1, 2, 3, 4], [5, 6, 3, 4]) -> [1, 2, 3, 4, 5, 6] |
| array_except(array1, array2) | 返回出现在第一个数组中但不在第二个数组中的元素组成的数组。array_except([1, 2, 3, 4], [5, 6, 3, 4]) -> [1, 2] |
| array_resize(array, size, value) | 调整列表大小使其包含 size 个元素。若未设置 value,则新元素初始化为空,否则用 value 初始化。array_resize([1, 2, 3], 5, 0) -> [1, 2, 3, 0, 0] |
| array_sort(array, desc, null_first) | 返回排序后的数组。array_sort([3, 1, 2, 5, 4]) -> [1, 2, 3, 4, 5] |
| cardinality(array/map) |
正则表达式
| 语法 | 说明 |
|---|---|
| regexp_match | 对字符串执行正则表达式匹配,并返回匹配到的子串。 |
| regexp_replace | 替换与正则表达式匹配的字符串 |
时间表达式
| 语法 | 说明 |
|---|---|
| date_part | 从日期中提取子字段。 |
| date_trunc | 将日期截断到指定的精度级别。 |
| from_unixtime | 以指定格式返回 unix 时间。 |
| to_timestamp | 将字符串转换为 Timestamp(_, _) |
| to_timestamp_millis | 将字符串转换为 Timestamp(Milliseconds, None) |
| to_timestamp_micros | 将字符串转换为 Timestamp(Microseconds, None) |
| to_timestamp_seconds | 将字符串转换为 Timestamp(Seconds, None) |
| now() | 返回当前时间。 |
其他表达式
| 语法 | 说明 |
|---|---|
| array([value1, …]) | 返回一个固定大小的数组,其中包含各个参数([value1, ...])。 |
| in_list(expr, list, negated) | 如果(expr)属于(或经 negated 取反后不属于)列表(list),则返回 true,否则返回 false。 |
| random() | 返回一个介于 0(含)到 1(不含)之间的随机值。 |
| sha224(text) | 计算参数(text)的 SHA224 哈希值。 |
| sha256(text) | 计算参数(text)的 SHA256 哈希值。 |
| sha384(text) | 计算参数(text)的 SHA384 哈希值。 |
| sha512(text) | 计算参数(text)的 SHA512 哈希值。 |
| to_hex(integer) | 将整数(integer)转换为对应的十六进制字符串。 |
聚合函数
| 语法 | 描述 |
|---|---|
| avg(expr) | 计算 expr 的平均值。 |
| avg_distinct(expr) | 创建一个用于表示 avg(distinct) 聚合函数的表达式 |
| approx_distinct(expr) | 计算 expr 中不同值数量的近似值。 |
| approx_median(expr) | 计算 expr 中位数的近似值。 |
| approx_percentile_cont(expr, percentile [, centroids]) | 计算 expr 指定 percentile 的近似值。可选的 centroids 参数用于控制精度(默认:100)。 |
| approx_percentile_cont_with_weight(expr, weight_expr, percentile [, centroids]) | 计算 expr 与 weight_expr 指定 percentile 的近似值。可选的 centroids 参数用于控制精度(默认:100)。 |
| bit_and(expr) | 计算 expr 所有非空输入值的按位与。 |
| bit_or(expr) | 计算 expr 所有非空输入值的按位或。 |
| bit_xor(expr) | 计算 expr 所有非空输入值的按位异或。 |
| bool_and(expr) | 如果 expr 的所有非空输入值都为 true,则返回 true,否则返回 false。 |
| bool_or(expr) | 如果 expr 的任一非空输入值为 true,则返回 true,否则返回 false。 |
| count(expr) | 返回 expr 的行数。 |
| count_distinct(expr) | 创建一个用于表示 count(distinct) 聚合函数的表达式 |
| cube(exprs) | 为 exprs 的所有组合创建分组集 |
| grouping_set(exprs) | 创建分组集。 |
| max(expr) | 求 expr 的最大值。 |
| median(expr) | 计算 expr 的中位数。 |
| min(expr) | 求 expr 的最小值。 |
| rollup(exprs) | 为 rollup 集合创建分组集。 |
| sum(expr) | 计算 expr 的总和。 |
| sum_distinct(expr) | 创建一个用于表示 sum(distinct) 聚合函数的表达式 |
Aggregate Function Builder
你还可以使用 ExprFunctionExt trait 更轻松地构建聚合函数参数 Expr。
示例用法参见 datafusion-examples/examples/query_planning/expr_api.rs。
| 语法 | 等价于 |
|---|---|
| first_value_udaf.call(vec![expr]).order_by(vec![expr]).build().unwrap() | first_value(expr, Some(vec![expr])) |
Subquery Expressions
| 语法 | 说明 |
|---|---|
| exists | 创建 EXISTS 子查询表达式 |
| in_subquery | df1.filter(in_subquery(col("foo"), df2))? 等价于 SQL 中的 WHERE foo IN <df2> |
| not_exists | 创建 NOT EXISTS 子查询表达式 |
| not_in_subquery | 创建 NOT IN 子查询表达式 |
| scalar_subquery | 创建标量子查询表达式 |
User-Defined Function Expressions
| 语法 | 说明 |
|---|---|
| create_udf | 创建具有特定签名和特定返回类型的新 UDF。 |
| create_udaf | 创建具有特定签名、状态类型和返回类型的新 UDAF。 |
评论
登录后参与评论
KnowForge