首页 / 工具 / 迁移清单 / Hive → MaxCompute
Hive 迁移到 MaxCompute 的函数改写清单
从 Hive 迁移到 MaxCompute 时,在 Hive 有对应写法的 44 个常用函数中,7 个需要改写,另有 5 个可以改用 MaxCompute 的原生函数。逐个列出两边写法和注意事项。
需要改写的函数 · 可以改用原生函数 · 迁移注意事项 · 可以直接用的函数 · 反向:MaxCompute 迁移到 Hive
需要改写的函数
| 函数 | Hive 写法 | MaxCompute 写法 | MaxCompute 说明 |
|---|---|---|---|
| DATEADD | date_add(startdate, days) / add_months(startdate, n) | 支持 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 | trunc(date, 'MM') | 支持 DATETRUNC(date, date_part) | 返回类型与输入相同。单位支持 yyyy、q、mm、week、isoweek、dd、hh、mi、ss、ff3,week 默认从周一开始,也可以写 week(sunday)。 |
| FROM_JSON | json_tuple(jsonStr, k1, k2, ...) | 支持 from_json(jsonStr, schema) | schema 写法与建表时的类型一致,例如 'a bigint, b double'、'array<bigint>'、'map<string,string>'。返回 ARRAY、MAP 或 STRUCT。STRUCT 的 key 区分大小写,缺失的 key 返回 NULL,类型不匹配的值会被忽略。 |
| GETDATE | current_timestamp | 支持 GETDATE() | 返回 DATETIME,以东八区时间为标准。同一条 SQL 中总是返回固定值,精度到秒;开启 2.0 数据类型后精度到毫秒。 |
| SPLIT_PART | split(str, pat)[n - 1] | 支持 SPLIT_PART(str, delimiter, start[, end]) | 下标从 1 开始,必须是大于 0 的常量。传入 end 时返回 start 到 end 段,并保留中间的分隔符。下标越界返回空字符串,分隔符为空字符串时返回原串,任一参数为 NULL 时返回 NULL。 |
| TO_CHAR | date_format(ts, 'yyyy-MM-dd HH:mm:ss') | 支持 TO_CHAR(date, format) | 格式符为 yyyy、mm、dd、hh、mi、ss,也支持 %Y、%m 这类写法。日期输入时 format 必填。date 为 NULL 时报错,format 为 NULL 时返回 NULL。也可以传入 BIGINT、DOUBLE 等数值,直接转成字符串。 |
| WM_CONCAT | concat_ws(',', collect_list(col)) | 支持 WM_CONCAT(separator, colname) | 分隔符必须是常量且写在前面。支持 DISTINCT 和 WITHIN GROUP (ORDER BY ...),值为 NULL 的行不参与计算。 |
可以改用原生函数
下面的函数在 Hive 中只能用替代写法,MaxCompute 有对应的函数。原来的写法通常仍能运行,换成原生函数会更简洁。
| 函数 | Hive 写法 | MaxCompute 写法 | MaxCompute 说明 |
|---|---|---|---|
| ANY_VALUE | max(col) | 支持 ANY_VALUE(colname) | 值为 NULL 的行不参与计算,不保证返回哪一行。 |
| APPROX_COUNT_DISTINCT | COUNT(DISTINCT col) | 别名 APPROX_DISTINCT(colname) | MaxCompute 2.0 扩展函数,返回 BIGINT,文档写明会有 5% 的误差。 |
| DAYOFWEEK | extract(dayofweek FROM ts) | 支持 DAYOFWEEK(date) | 返回 1~7,1 是周日,7 是周六。WEEKDAY(date) 则以周一为 0、周日为 6。 |
| DECODE | CASE expr WHEN search THEN result ... ELSE default END | 支持 DECODE(expression, search, result[, search, result]...[, default]) | 没有匹配且没有 default 时返回 NULL。所有 result 的类型必须一致,search 与 expression 的类型也必须一致,否则报错。在 DECODE 中 NULL 与 NULL 视为相等。 |
| MAX_BY | ROW_NUMBER() OVER (PARTITION BY ... ORDER BY y DESC) = 1 | 支持 MAX_BY(valueToReturn, valueToMaximize) | valueToMaximize 为 NULL 的行不参与计算。多行并列最大时随机返回其中一行。 |
迁移注意事项
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 文档的示例也截断到周一。按周汇总前确认业务定义的周起点。
- Hive 的 trunc 只能截断到月和年,按周、按季度汇总需要自己计算。
FROM_JSON 按 schema 解析 JSON
- MaxCompute 的 from_json 解析成 FLOAT、DOUBLE 或 DECIMAL 时不保证精度。金额类字段建议先按 STRING 取出,再 CAST 成 DECIMAL。
- MaxCompute 的 STRUCT key 区分大小写。JSON 里是 userId、schema 里写成 userid 时,取到的是 NULL,并且不会报错。
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() 更容易对齐。
SPLIT_PART 按分隔符取第 N 段
- 下标越界时结果不同:MaxCompute、StarRocks 和 Spark 返回空字符串,Hologres 和 Doris 返回 NULL。下游用 IS NULL 或 = '' 判断时,迁移后结果可能变化。
- Hive 的 split 按正则切分。分隔符是 .、| 这类正则特殊字符时,要写成 split(s, '\\.'),否则结果不对。
- Hive 的数组下标和 Flink 的 SPLIT_INDEX 都从 0 开始。从 SPLIT_PART 改写时要把下标减 1。
- 取最后一段时,StarRocks 和 Spark 可以直接传 -1。MaxCompute 要求下标大于 0,不能这样写。
- MaxCompute 的四参数写法 SPLIT_PART(s, ',', 1, 2) 在其他引擎中没有对应写法,需要改成多段拼接。
TO_CHAR 日期转字符串
- MaxCompute 的 'yyyy-mm-dd' 原样搬到 Hive、Spark 或 Flink,mm 会被当成分钟,结果类似 2026-30-14,而且不会报错。Java 风格要写 'yyyy-MM-dd'。
- MaxCompute 的 TO_CHAR 遇到 date 为 NULL 会报错,而不是返回 NULL。
WM_CONCAT 分组拼接字符串
- 不写排序时,各引擎拼接的顺序都不固定。需要稳定结果时,MaxCompute 写 WITHIN GROUP (ORDER BY ...),StarRocks 和 Doris 在 GROUP_CONCAT 内写 ORDER BY。
ANY_VALUE 取组内任意值
- NULL 的处理不同:MaxCompute 和 Doris 会优先返回非 NULL 值,Spark 默认可能返回 NULL,需要传 true 才会跳过 NULL。
APPROX_COUNT_DISTINCT 近似去重计数
- 各引擎的误差不同:MaxCompute 文档写的是 5%,Hologres 默认是 0.1%~1%。迁移后与原报表对数时,小的差异属于正常现象,不能直接当作数据问题。
- 改写成 Hive 或 Flink 的 COUNT(DISTINCT) 后结果是精确值,但资源消耗会明显变大,大数据量下要评估内存和运行时间。
DAYOFWEEK 星期几
- “星期几”的编号有三种:DAYOFWEEK 周日为 1;MaxCompute 和 Spark 的 WEEKDAY 周一为 0;Hologres 的 ISODOW 周一为 1、周日为 7。迁移时先确认原 SQL 用的是哪一种。
- Hive 的内置函数文档没有 dayofweek,只能用 Hive 2.2.0 起提供的 extract(dayofweek FROM ...)。
DECODE 多值匹配
- MaxCompute 的 DECODE 把 NULL 和 NULL 视为相等,DECODE(x, NULL, 0, 1) 在 x 为 NULL 时返回 0。改写成 CASE x WHEN NULL THEN 0 ... 永远不会匹配,要写成 CASE WHEN x IS NULL THEN 0 ...。
- Hive 和 Flink 也有 DECODE,但含义是字符集解码。把 MaxCompute 的多参数 DECODE 原样搬过去会报参数错误,必须改写成 CASE。
- MaxCompute 要求所有 result 类型一致,例如 DECODE(x, 1, 1, 2, 'b') 会报错。改写成 CASE 后各引擎的隐式转换规则不同,建议显式 CAST。
MAX_BY 取最大值对应的列
- 并列最大时结果不确定:MaxCompute 随机返回一行,StarRocks 返回最先遇到的一行。需要稳定结果时,改用 ROW_NUMBER 并在 ORDER BY 中加上唯一的次排序列。
可以直接用的函数
下面 32 个函数在两个引擎中写法相同。参数、返回值和边界情况仍可能不同,点开函数页查看细节。
- ADD_MONTHS 按月加减
- ARRAY_CONTAINS 判断数组是否包含元素
- COALESCE 取第一个非空值
- COLLECT_LIST 聚合为数组
- COLLECT_SET 去重聚合为数组
- CONCAT 字符串拼接
- CONCAT_WS 按分隔符拼接
- DATE_ADD 日期加减
- DATE_FORMAT 日期格式化
- DATE_SUB 日期减天数
- DATEDIFF 日期差
- EXPLODE 数组展开为多行
- FROM_UNIXTIME 时间戳转日期
- GET_JSON_OBJECT 提取 JSON 字段
- IF 条件判断
- INSTR 查找子串位置
- LAST_DAY 当月最后一天
- LENGTH 字符串长度
- MONTHS_BETWEEN 相差月数
- NVL 空值替换
- PERCENTILE_APPROX 近似分位数
- REGEXP_EXTRACT 正则提取
- REGEXP_REPLACE 正则替换
- SIZE 数组和 Map 元素个数
- SORT_ARRAY 数组排序
- SPLIT 字符串拆分
- STR_TO_MAP 字符串转 Map
- SUBSTR 截取子串
- SUBSTRING_INDEX 按分隔符截取
- TO_DATE 字符串转日期
- UNIX_TIMESTAMP 日期转时间戳
- WEEKOFYEAR 一年中的第几周