首页 / 工具 / 迁移清单 / Spark SQL → MaxCompute
Spark SQL 迁移到 MaxCompute 的函数改写清单
从 Spark SQL 迁移到 MaxCompute 时,在 Spark SQL 有对应写法的 44 个常用函数中,5 个需要改写。逐个列出两边写法和注意事项。
需要改写的函数 · 迁移注意事项 · 可以直接用的函数 · 反向:MaxCompute 迁移到 Spark SQL
需要改写的函数
| 函数 | Spark SQL 写法 | MaxCompute 写法 | MaxCompute 说明 |
|---|---|---|---|
| APPROX_COUNT_DISTINCT | approx_count_distinct(expr[, relativeSD]) | 别名 APPROX_DISTINCT(colname) | MaxCompute 2.0 扩展函数,返回 BIGINT,文档写明会有 5% 的误差。 |
| DATEADD | ts + INTERVAL n HOUR | 支持 DATEADD(date, delta, datepart) | datepart 必须是常量,可选 yyyy、q、mm、week、dd、hh、mi、ss、ff3 等。返回类型与 date 相同。date 为 NULL 时报错,delta 或 datepart 为 NULL 时返回 NULL。2.0 数据类型版本下,字符串要先 CAST 成 DATETIME。 |
| DATETRUNC | date_trunc('MONTH', ts) | 支持 DATETRUNC(date, date_part) | 返回类型与输入相同。单位支持 yyyy、q、mm、week、isoweek、dd、hh、mi、ss、ff3,week 默认从周一开始,也可以写 week(sunday)。 |
| GETDATE | current_timestamp() 或 now() | 支持 GETDATE() | 返回 DATETIME,以东八区时间为标准。同一条 SQL 中总是返回固定值,精度到秒;开启 2.0 数据类型后精度到毫秒。 |
| WM_CONCAT | string_agg(expr[, delimiter]) WITHIN GROUP (ORDER BY ...) | 支持 WM_CONCAT(separator, colname) | 分隔符必须是常量且写在前面。支持 DISTINCT 和 WITHIN GROUP (ORDER BY ...),值为 NULL 的行不参与计算。 |
迁移注意事项
APPROX_COUNT_DISTINCT 近似去重计数
- 各引擎的误差不同:MaxCompute 文档写的是 5%,Hologres 默认是 0.1%~1%。迁移后与原报表对数时,小的差异属于正常现象,不能直接当作数据问题。
- Spark 的第二个参数 relativeSD 在其他引擎中没有对应写法,迁移时要去掉,并按目标引擎的方式调整精度,例如 Hologres 的会话参数。
DATEADD 按单位加减日期
- MaxCompute 和 Hologres 中 mm 表示月,mi 表示分钟。把 DATEADD(d, 1, 'mm') 当成加 1 分钟,是迁移时最常见的错误。
- Spark 3.4.0 起的 dateadd(d, 1) 表示加 1 天,参数个数和含义都与 MaxCompute 不同,不能直接照搬。
- MaxCompute 的 DATEADD 遇到 date 为 NULL 会报错,而不是返回 NULL。字段可能为空时,先过滤或用 IF 包一层。
- MaxCompute 按月加减时,如果目标月份没有对应日期,结果取当月最后一天。StarRocks 的 DATE_ADD 遇到不存在的日期返回 NULL。
DATETRUNC 日期截断
- 参数顺序不同:MaxCompute 是日期在前,Hologres、StarRocks 和 Spark 是单位在前,Doris 两种都接受。
- 返回类型不同:MaxCompute 对 DATE 输入返回 DATE,Hologres 和 Spark 的 date_trunc 返回时间戳。结果用于关联 DATE 字段时要先转换。
- 周的起点:MaxCompute 的 week 默认从周一开始,Doris 和 Spark 文档的示例也截断到周一。按周汇总前确认业务定义的周起点。
GETDATE 获取当前时间
- MaxCompute 的 GETDATE 固定使用东八区,其他引擎的结果取决于会话或集群时区。迁移后如果时间差了 8 小时,先检查时区设置。
- 返回类型不同:MaxCompute、StarRocks 和 Doris 返回 DATETIME,Hologres 的 NOW 带时区(文档把不带时区的版本单独列为 LOCALTIMESTAMP),Flink 返回 TIMESTAMP_LTZ(3)。直接写入字符串或 DATETIME 字段时,格式可能变化。
- 精度不同:MaxCompute 默认到秒,StarRocks 和 Doris 默认到秒、可传参数到微秒,Flink 到毫秒。用当前时间做去重或比较时要注意小数部分。
- Hive 和 Spark 的 current_timestamp 可以不带括号,Doris 文档中的写法是 current_timestamp()。迁移时统一写 NOW() 更容易对齐。
WM_CONCAT 分组拼接字符串
- 不写排序时,各引擎拼接的顺序都不固定。需要稳定结果时,MaxCompute 写 WITHIN GROUP (ORDER BY ...),StarRocks 和 Doris 在 GROUP_CONCAT 内写 ORDER BY。
可以直接用的函数
下面 39 个函数在两个引擎中写法相同。参数、返回值和边界情况仍可能不同,点开函数页查看细节。
- ADD_MONTHS 按月加减
- ANY_VALUE 取组内任意值
- ARRAY_CONTAINS 判断数组是否包含元素
- COALESCE 取第一个非空值
- COLLECT_LIST 聚合为数组
- COLLECT_SET 去重聚合为数组
- CONCAT 字符串拼接
- CONCAT_WS 按分隔符拼接
- DATE_ADD 日期加减
- DATE_FORMAT 日期格式化
- DATE_SUB 日期减天数
- DATEDIFF 日期差
- DAYOFWEEK 星期几
- DECODE 多值匹配
- EXPLODE 数组展开为多行
- FROM_JSON 按 schema 解析 JSON
- FROM_UNIXTIME 时间戳转日期
- GET_JSON_OBJECT 提取 JSON 字段
- IF 条件判断
- INSTR 查找子串位置
- LAST_DAY 当月最后一天
- LENGTH 字符串长度
- MAX_BY 取最大值对应的列
- MONTHS_BETWEEN 相差月数
- NVL 空值替换
- PERCENTILE_APPROX 近似分位数
- REGEXP_EXTRACT 正则提取
- REGEXP_REPLACE 正则替换
- SIZE 数组和 Map 元素个数
- SORT_ARRAY 数组排序
- SPLIT 字符串拆分
- SPLIT_PART 按分隔符取第 N 段
- STR_TO_MAP 字符串转 Map
- SUBSTR 截取子串
- SUBSTRING_INDEX 按分隔符截取
- TO_CHAR 日期转字符串
- TO_DATE 字符串转日期
- UNIX_TIMESTAMP 日期转时间戳
- WEEKOFYEAR 一年中的第几周