首页 / 工具 / 迁移清单 / Flink SQL → StarRocks
Flink SQL 迁移到 StarRocks 的函数改写清单
从 Flink SQL 迁移到 StarRocks 时,在 Flink SQL 有对应写法的 43 个常用函数中,15 个需要改写,另有 3 个可以改用 StarRocks 的原生函数。逐个列出两边写法和注意事项。
需要改写的函数 · 可以改用原生函数 · 迁移注意事项 · 可以直接用的函数 · 反向:StarRocks 迁移到 Flink SQL
需要改写的函数
| 函数 | Flink SQL 写法 | StarRocks 写法 | StarRocks 说明 |
|---|---|---|---|
| ADD_MONTHS | TIMESTAMPADD(MONTH, n, timepoint) | 支持 add_months(date, months) | 返回 DATETIME,DATE 输入也会转成 DATETIME。目标月份没有对应日期时返回当月最后一天,例如 2022-01-31 加 1 个月得到 2022-02-28。 |
| DATE_ADD | TIMESTAMPADD(DAY, n, timepoint) | 支持 DATE_ADD(date, INTERVAL n DAY) | 文档只列出 INTERVAL 写法。返回 DATETIME,DATE 输入也会转成 DATETIME。结果日期不存在时返回 NULL。 |
| DATE_SUB | TIMESTAMPADD(DAY, -n, timepoint) | 支持 DATE_SUB(date, INTERVAL n DAY) | 别名 subdate。返回 DATETIME。结果日期不存在时返回 NULL,例如 2010-02-30。只传天数时可以用 days_sub(d, n)。 |
| DATEDIFF | TIMESTAMPDIFF(DAY, timepoint1, timepoint2) | 支持 DATEDIFF(expr1, expr2) | 结果为 expr1 减 expr2,只按天计算,忽略时间部分。需要其他单位时用 date_diff。 |
| DATETRUNC | FLOOR(timepoint TO MONTH) | 需改写 date_trunc('month', datetime) | 单位在前且必须是常量。DATE 输入只能截断到 year、quarter、month、week、day。 |
| FROM_JSON | JSON_VALUE(json, path) / JSON_QUERY(json, path) | 需改写 parse_json(str) | 没有 FROM_JSON。parse_json 返回 JSON 类型,而不是 STRUCT 或 MAP。字符串不是合法 JSON 时返回 NULL。取字段可以接 json_query 或 -> 运算符。 |
| GET_JSON_OBJECT | JSON_VALUE(json, path) | 支持 get_json_object(json_str, json_path) | 文档中 get_json_string 和 get_json_object 是同一条目,返回字符串。需要保留 JSON 类型时用 json_query 或箭头操作符。 |
| LAST_DAY | TIMESTAMPADD(DAY, -1, TIMESTAMPADD(MONTH, 1, FLOOR(ts TO MONTH))) | 支持 last_day(date[, unit]) | 3.1 起提供,返回 DATE。unit 可以是 month、quarter 或 year,默认 month。 |
| MONTHS_BETWEEN | TIMESTAMPDIFF(MONTH, start, end) | 需改写 months_diff(expr1, expr2) | 函数列表中没有 MONTHS_BETWEEN。months_diff 返回 expr1 减 expr2 的月数,类型是 BIGINT,只精确到月;日期不存在时返回 NULL。 |
| PERCENTILE_APPROX | PERCENTILE(expr, percentage[, frequency]) | 支持 PERCENTILE_APPROX(expr, p[, compression]) | p 可以是单个值或数组。compression 取 2048~10000,不传或超出范围时按 10000 计算,值越大越精确,内存占用也越多。 |
| SIZE | CARDINALITY(array_or_map) | 别名 array_length(arr) / map_size(m) | 数组用 array_length,别名 cardinality,3.0 起提供,NULL 元素也计入长度,输入为 NULL 时返回 NULL。Map 用 map_size,2.5 起提供,别名同样是 cardinality。 |
| SPLIT_PART | SPLIT_INDEX(str, delimiter, n - 1) | 支持 split_part(content, delimiter, field) | 正数从开头数,负数从末尾数,-1 表示最后一段。下标越界时,官方示例返回空字符串。 |
| TO_DATE | TO_DATE(string1[, string2]) | 需改写 str_to_date(str, format) | StarRocks 的 to_date 只接受 DATETIME 并取日期部分,不能解析字符串。按格式解析用 str_to_date,格式符与 date_format 相同;格式只含日期时返回 DATE,否则返回 DATETIME。 |
| WEEKOFYEAR | WEEK(date) | 支持 WEEKOFYEAR(date) | 返回 INT。文档没有说明周的划分规则;需要 ISO 周时可以用 week_iso。 |
| WM_CONCAT | LISTAGG(expression[, separator]) | 需改写 GROUP_CONCAT([DISTINCT] expr [ORDER BY ...] [SEPARATOR sep]) | 默认分隔符是逗号,跳过 NULL。结果长度受 group_concat_max_len 限制,默认 1,024 个字符,超出部分会被截断。 |
可以改用原生函数
下面的函数在 Flink SQL 中只能用替代写法,StarRocks 有对应的函数。原来的写法通常仍能运行,换成原生函数会更简洁。
| 函数 | Flink SQL 写法 | StarRocks 写法 | StarRocks 说明 |
|---|---|---|---|
| ANY_VALUE | FIRST_VALUE(expression) | 支持 ANY_VALUE(expr) | 返回值不确定。3.2 起支持 ARRAY、MAP 和 STRUCT 类型。 |
| APPROX_COUNT_DISTINCT | COUNT(DISTINCT expr) | 支持 APPROX_COUNT_DISTINCT(expr) | 结果近似于 COUNT(DISTINCT col),使用固定大小的内存,适合高基数列。 |
| MAX_BY | ROW_NUMBER() OVER (PARTITION BY ... ORDER BY y DESC) = 1 | 支持 max_by(x, y) | 2.5 起提供。y 为 NULL 的行被忽略,并列时返回最先遇到的 x。y 不能是 bitmap、hll 等不可排序的类型。 |
迁移注意事项
ADD_MONTHS 按月加减
- 月末日期:StarRocks、Doris 和 Spark 在目标月份没有对应日期时取当月最后一天。StarRocks 文档特别说明,2022-02-28 加 1 个月得到 3 月 28 日而不是 3 月 31 日,这和 Oracle 的行为不同。
- Hologres 和 Flink 的月末行为文档没有写明,迁移涉及月末日期时建议用已知数据核对。
DATE_ADD 日期加减
- MaxCompute 的 DATEADD 按月加时,目标月份没有对应日期会返回当月最后一天,例如 1 月 29 日加 1 个月得到 2 月 28 日。StarRocks 的 DATE_ADD 遇到不存在的日期返回 NULL。
- StarRocks 的 DATE_ADD 即使输入是 DATE,也会返回 DATETIME。写入 DATE 列或与 DATE 比较时注意类型。
DATE_SUB 日期减天数
- StarRocks 的 DATE_SUB 即使输入是 DATE,也返回 DATETIME。结果用于分区过滤或与 DATE 字段比较时,注意类型是否一致。
- StarRocks 和 Doris 的 DATE_SUB 文档只列出 INTERVAL 写法。把 Hive 的 date_sub(d, 1) 搬到 StarRocks 时,改成 DATE_SUB(d, INTERVAL 1 DAY) 或 days_sub(d, 1)。
DATEDIFF 日期差
- MaxCompute、StarRocks、Doris、Hive 和 Spark 都是结束日期在前。Flink 的 TIMESTAMPDIFF 先写单位,再写开始时间和结束时间。Flink 文档没有写明正负号的方向,按标准 SQL 的约定结果为 timepoint2 减 timepoint1,迁移后建议用一条已知数据核对符号。
- StarRocks 只比较日期部分:DATEDIFF('2007-12-31 23:59:59', '2007-12-30') 返回 1,而不是按 47 小时折算。
DATETRUNC 日期截断
- 参数顺序不同:MaxCompute 是日期在前,Hologres、StarRocks 和 Spark 是单位在前,Doris 两种都接受。
FROM_JSON 按 schema 解析 JSON
- StarRocks 的 parse_json 和 Doris 的 JSON_PARSE 返回的是 JSON 类型,下游需要 STRUCT 或 MAP 时要再做一次转换,不能直接替换 from_json。
- 非法 JSON 的处理不同:StarRocks 的 parse_json 返回 NULL,Doris 的 JSON_PARSE 直接报错。脏数据较多的表,在 Doris 中改用 JSON_PARSE_ERROR_TO_NULL。
GET_JSON_OBJECT 提取 JSON 字段
- StarRocks 和 Doris 返回字符串,取出的数字需要再做 CAST。Doris 中值无法无损转换为字符串时返回 NULL。
LAST_DAY 当月最后一天
- 返回类型不同:MaxCompute(不传 date_part)和 Hive 返回字符串,StarRocks 和 Doris 返回 DATE。结果用于关联 DATE 字段时要先转换。
MONTHS_BETWEEN 相差月数
- Flink 的 TIMESTAMPDIFF(MONTH, t1, t2) 计算的是 t2 减 t1,开始时间在前;MONTHS_BETWEEN 是结束时间在前。照搬参数顺序会得到相反的符号。
- StarRocks 的 months_diff、Flink 的 TIMESTAMPDIFF 和 Hologres 的 EXTRACT 写法都只返回整数月,原 SQL 中依赖小数部分的计算(例如按 0.5 个月判断)需要重新设计。
PERCENTILE_APPROX 近似分位数
- 第三个参数含义不同:MaxCompute 和 Hive 的 B、Spark 的 accuracy 都默认 10000;StarRocks 和 Doris 的 compression 只接受 2048~10000。从 Spark 迁移时,如果写了大于 10000 的 accuracy,要调整到这个范围内。
- 各引擎的算法不同,结果不会完全一致。MaxCompute 文档写明 p 落在两个值中间时取两者均值,Spark 返回满足条件的最小值,Flink 的 PERCENTILE 用线性插值。P50、P99 这类指标迁移后要实测对比。
- Flink 的 PERCENTILE 是精确计算,每条记录都可能触发全量排序。文档建议用在窗口聚合中,流式分组聚合中慎用。
SIZE 数组和 Map 元素个数
- StarRocks 和 Doris 区分数组和 Map 函数。从 MaxCompute 或 Hive 迁移时,要按字段类型分别改成 array_length、map_size 或 ARRAY_SIZE、MAP_SIZE。
- StarRocks 和 Doris 文档写明 NULL 元素也计入个数。需要只统计非空元素时,要先过滤再计数。
SPLIT_PART 按分隔符取第 N 段
- 下标越界时结果不同:MaxCompute、StarRocks 和 Spark 返回空字符串,Hologres 和 Doris 返回 NULL。下游用 IS NULL 或 = '' 判断时,迁移后结果可能变化。
- Hive 的数组下标和 Flink 的 SPLIT_INDEX 都从 0 开始。从 SPLIT_PART 改写时要把下标减 1。
- 取最后一段时,StarRocks 和 Spark 可以直接传 -1。MaxCompute 要求下标大于 0,不能这样写。
TO_DATE 字符串转日期
- 同名不同义:把 MaxCompute 的 TO_DATE('20261013', 'yyyymmdd') 直接搬到 StarRocks、Doris 或 Hive 会报错或得到错误结果,需要改用 str_to_date 或 unix_timestamp。
- MaxCompute 的格式符里 mm 是月、mi 是分钟;Spark 和 Flink 里 MM 是月、mm 是分钟。
WEEKOFYEAR 一年中的第几周
- StarRocks 文档没有写明 WEEKOFYEAR 的周规则。需要和其他引擎对齐时,建议改用 week_iso 并实测。
WM_CONCAT 分组拼接字符串
- StarRocks 的 GROUP_CONCAT 默认最多 1,024 个字符,超出部分不报错直接截断。长列表需要先调大 group_concat_max_len。
- 不写排序时,各引擎拼接的顺序都不固定。需要稳定结果时,MaxCompute 写 WITHIN GROUP (ORDER BY ...),StarRocks 和 Doris 在 GROUP_CONCAT 内写 ORDER BY。
- StarRocks 3.0.6 和 3.1.3 起,GROUP_CONCAT 必须用 SEPARATOR 关键字声明分隔符。
APPROX_COUNT_DISTINCT 近似去重计数
- 改写成 Hive 或 Flink 的 COUNT(DISTINCT) 后结果是精确值,但资源消耗会明显变大,大数据量下要评估内存和运行时间。
MAX_BY 取最大值对应的列
- 并列最大时结果不确定:MaxCompute 随机返回一行,StarRocks 返回最先遇到的一行。需要稳定结果时,改用 ROW_NUMBER 并在 ORDER BY 中加上唯一的次排序列。
可以直接用的函数
下面 25 个函数在两个引擎中写法相同。参数、返回值和边界情况仍可能不同,点开函数页查看细节。
- ARRAY_CONTAINS 判断数组是否包含元素
- COALESCE 取第一个非空值
- COLLECT_LIST 聚合为数组
- COLLECT_SET 去重聚合为数组
- CONCAT 字符串拼接
- CONCAT_WS 按分隔符拼接
- DATE_FORMAT 日期格式化
- DATEADD 按单位加减日期
- DAYOFWEEK 星期几
- DECODE 多值匹配
- EXPLODE 数组展开为多行
- FROM_UNIXTIME 时间戳转日期
- GETDATE 获取当前时间
- IF 条件判断
- INSTR 查找子串位置
- LENGTH 字符串长度
- NVL 空值替换
- REGEXP_EXTRACT 正则提取
- REGEXP_REPLACE 正则替换
- SORT_ARRAY 数组排序
- SPLIT 字符串拆分
- STR_TO_MAP 字符串转 Map
- SUBSTR 截取子串
- TO_CHAR 日期转字符串
- UNIX_TIMESTAMP 日期转时间戳