首页 / 工具 / 迁移清单 / Doris → StarRocks
Doris 迁移到 StarRocks 的函数改写清单
从 Doris 迁移到 StarRocks 时,在 Doris 有对应写法的 44 个常用函数中,11 个需要改写。逐个列出两边写法和注意事项。
需要改写的函数 · 迁移注意事项 · 可以直接用的函数 · 反向:StarRocks 迁移到 Doris
需要改写的函数
| 函数 | Doris 写法 | StarRocks 写法 | StarRocks 说明 |
|---|---|---|---|
| ADD_MONTHS | MONTHS_ADD(date, nums) | 支持 add_months(date, months) | 返回 DATETIME,DATE 输入也会转成 DATETIME。目标月份没有对应日期时返回当月最后一天,例如 2022-01-31 加 1 个月得到 2022-02-28。 |
| COLLECT_LIST | COLLECT_LIST(expr[, max_size]) | 需改写 ARRAY_AGG(col [ORDER BY ...]) | 在 StarRocks 文档中搜索不到 COLLECT_LIST。ARRAY_AGG 会保留 NULL,3.0 起支持 ORDER BY 指定元素顺序。 |
| COLLECT_SET | COLLECT_SET(expr[, max_size]) | 需改写 ARRAY_AGG(DISTINCT col) | 在 StarRocks 文档中搜索不到 COLLECT_SET。ARRAY_AGG_DISTINCT 是 ARRAY_AGG(DISTINCT) 的别名。ARRAY_AGG 会保留 NULL。 |
| EXPLODE | LATERAL VIEW EXPLODE(arr) t AS x | 需改写 FROM t, UNNEST(arr) AS u(x) | UNNEST 是表函数,配合横向连接使用,不需要写 LATERAL。NULL 或空数组不输出行;3.2.7 起可以用 LEFT JOIN ... ON TRUE 保留这些行。 |
| FROM_JSON | JSON_PARSE(json_str) | 需改写 parse_json(str) | 没有 FROM_JSON。parse_json 返回 JSON 类型,而不是 STRUCT 或 MAP。字符串不是合法 JSON 时返回 NULL。取字段可以接 json_query 或 -> 运算符。 |
| GET_JSON_OBJECT | GET_JSON_STRING(json_str, json_path) | 支持 get_json_object(json_str, json_path) | 文档中 get_json_string 和 get_json_object 是同一条目,返回字符串。需要保留 JSON 类型时用 json_query 或箭头操作符。 |
| MONTHS_BETWEEN | MONTHS_BETWEEN(end, start[, round_type]) | 需改写 months_diff(expr1, expr2) | 函数列表中没有 MONTHS_BETWEEN。months_diff 返回 expr1 减 expr2 的月数,类型是 BIGINT,只精确到月;日期不存在时返回 NULL。 |
| NVL | NVL(expr1, expr2) | 需改写 IFNULL(expr1, expr2) | 条件函数列表中没有 NVL,只有 case、coalesce、if、ifnull 和 nullif。IFNULL 的结果类型与 expr1 一致。 |
| SIZE | ARRAY_SIZE(arr) / MAP_SIZE(m) | 别名 array_length(arr) / map_size(m) | 数组用 array_length,别名 cardinality,3.0 起提供,NULL 元素也计入长度,输入为 NULL 时返回 NULL。Map 用 map_size,2.5 起提供,别名同样是 cardinality。 |
| SPLIT | SPLIT_BY_STRING(str, separator) | 支持 split(content, delimiter) | 返回 ARRAY<VARCHAR>。分隔符为空字符串时按单个字符拆分。文档没有说明分隔符是否按正则处理。 |
| SUBSTR | SUBSTRING(str, pos[, len]) | 支持 substr(str, pos[, len]) | substr 和 substring 是同一个函数。从 1 开始计数,负数从末尾倒数,pos 为 0 或超出长度时返回空字符串。 |
迁移注意事项
ADD_MONTHS 按月加减
- 月末日期:StarRocks、Doris 和 Spark 在目标月份没有对应日期时取当月最后一天。StarRocks 文档特别说明,2022-02-28 加 1 个月得到 3 月 28 日而不是 3 月 31 日,这和 Oracle 的行为不同。
COLLECT_LIST 聚合为数组
- 不要依赖数组元素的顺序。MaxCompute 文档建议用 SORT_ARRAY 排序;StarRocks 可以直接写 ARRAY_AGG(x ORDER BY y)。
- StarRocks 的 ARRAY_AGG 保留 NULL,MaxCompute 和 Doris 的 COLLECT_LIST 丢弃 NULL,数组长度可能不一致。
COLLECT_SET 去重聚合为数组
- NULL 的处理不同:MaxCompute、Doris 会丢弃 NULL,StarRocks 的 ARRAY_AGG 会保留 NULL。迁移到 StarRocks 后数组里可能多出 NULL 元素。
- Doris 的 max_size 截断时保留哪些元素,文档没有说明,不要依赖它取“前 N 个”。
EXPLODE 数组展开为多行
- 空数组和 NULL 数组的行会被直接丢掉:MaxCompute、Doris 的 EXPLODE 和 StarRocks 的 UNNEST 都是这样。需要保留时,Doris 和 Spark 用 EXPLODE_OUTER,StarRocks 3.2.7 起用 LEFT JOIN UNNEST(...) ON TRUE。
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。
MONTHS_BETWEEN 相差月数
- StarRocks 的 months_diff、Flink 的 TIMESTAMPDIFF 和 Hologres 的 EXTRACT 写法都只返回整数月,原 SQL 中依赖小数部分的计算(例如按 0.5 个月判断)需要重新设计。
- 时间部分的处理不同:Doris 只看日期,Hive 会把时间部分算进小数,Spark 在同一天或都是月末时忽略时间。同样的输入可能得到不同的小数。
- 舍入不同:Hive 和 Spark 默认保留 8 位小数,MaxCompute 返回完整的 DOUBLE,Doris 由 round_type 控制。和原结果做等值比较前,先统一 ROUND。
NVL 空值替换
- 迁移到 Hologres、StarRocks 或 Flink SQL 时,统一改写为 COALESCE 最省事,因为 COALESCE 在七个引擎中都可用。
SIZE 数组和 Map 元素个数
- StarRocks 和 Doris 区分数组和 Map 函数。从 MaxCompute 或 Hive 迁移时,要按字段类型分别改成 array_length、map_size 或 ARRAY_SIZE、MAP_SIZE。
- StarRocks 和 Doris 文档写明 NULL 元素也计入个数。需要只统计非空元素时,要先过滤再计数。
SUBSTR 截取子串
- 起始位置写 0 是常见错误。MaxCompute 默认、StarRocks 和 Doris 都返回空字符串,不会报错,结果却全是空值,很难发现。MaxCompute 开启 Hive 兼容模式后又会按 1 处理,同一条 SQL 在不同模式下结果不同。
可以直接用的函数
下面 33 个函数在两个引擎中写法相同。参数、返回值和边界情况仍可能不同,点开函数页查看细节。
- ANY_VALUE 取组内任意值
- APPROX_COUNT_DISTINCT 近似去重计数
- ARRAY_CONTAINS 判断数组是否包含元素
- COALESCE 取第一个非空值
- CONCAT 字符串拼接
- CONCAT_WS 按分隔符拼接
- DATE_ADD 日期加减
- DATE_FORMAT 日期格式化
- DATE_SUB 日期减天数
- DATEADD 按单位加减日期
- DATEDIFF 日期差
- DATETRUNC 日期截断
- DAYOFWEEK 星期几
- DECODE 多值匹配
- FROM_UNIXTIME 时间戳转日期
- GETDATE 获取当前时间
- IF 条件判断
- INSTR 查找子串位置
- LAST_DAY 当月最后一天
- LENGTH 字符串长度
- MAX_BY 取最大值对应的列
- PERCENTILE_APPROX 近似分位数
- REGEXP_EXTRACT 正则提取
- REGEXP_REPLACE 正则替换
- SORT_ARRAY 数组排序
- SPLIT_PART 按分隔符取第 N 段
- STR_TO_MAP 字符串转 Map
- SUBSTRING_INDEX 按分隔符截取
- TO_CHAR 日期转字符串
- TO_DATE 字符串转日期
- UNIX_TIMESTAMP 日期转时间戳
- WEEKOFYEAR 一年中的第几周
- WM_CONCAT 分组拼接字符串