首页 / 工具 / 迁移清单 / StarRocks → Hive
StarRocks 迁移到 Hive 的函数改写清单
从 StarRocks 迁移到 Hive 时,在 StarRocks 有对应写法的 44 个常用函数中,19 个需要改写。逐个列出两边写法和注意事项。
需要改写的函数 · 迁移注意事项 · 可以直接用的函数 · 反向:Hive 迁移到 StarRocks
需要改写的函数
| 函数 | StarRocks 写法 | Hive 写法 | Hive 说明 |
|---|---|---|---|
| ANY_VALUE | ANY_VALUE(expr) | 需改写 max(col) | 函数手册中没有 ANY_VALUE,组内值都相同时用 max 或 min 代替。 |
| APPROX_COUNT_DISTINCT | APPROX_COUNT_DISTINCT(expr) | 需改写 COUNT(DISTINCT col) | 内置函数文档中没有近似去重函数,只能用精确的 COUNT(DISTINCT)。 |
| COLLECT_LIST | ARRAY_AGG(col [ORDER BY ...]) | 支持 collect_list(col) | Hive 0.13.0 起提供,保留重复值。 |
| COLLECT_SET | ARRAY_AGG(DISTINCT col) | 支持 collect_set(col) | 返回去重后的 array。 |
| DATEADD | TIMESTAMPADD(unit, n, datetime_expr) | 需改写 date_add(startdate, days) / add_months(startdate, n) | 内置函数中没有 DATEADD。按天加减用 date_add,按月加减用 add_months。 |
| DATETRUNC | date_trunc('month', datetime) | 需改写 trunc(date, 'MM') | 函数手册中没有 date_trunc。trunc 只支持 MONTH、MON、MM 和 YEAR、YYYY、YY,返回 string。 |
| DAYOFWEEK | dayofweek(date) | 需改写 extract(dayofweek FROM ts) | 内置函数文档中没有 dayofweek 函数,Hive 2.2.0 起可以用 extract 取 dayofweek,文档示例中 2016-10-20(周四)返回 5,即周日为 1。 |
| EXPLODE | FROM t, UNNEST(arr) AS u(x) | 支持 explode(array | map) | UDTF,数组展开为一列 col,map 展开为 key 和 value 两列。需要元素位置时用 posexplode,位置从 0 开始。 |
| FROM_JSON | parse_json(str) | 需改写 json_tuple(jsonStr, k1, k2, ...) | 内置函数中没有 FROM_JSON。一次取多个 key 用 json_tuple,它是 UDTF,要配合 LATERAL VIEW 使用;取单个值用 get_json_object。 |
| GETDATE | NOW([p]) | 别名 current_timestamp | Hive 1.2.0 起提供,返回查询开始时的时间戳,同一查询中各次调用结果相同。unix_timestamp() 无参写法从 2.0 起已废弃,文档建议改用 CURRENT_TIMESTAMP。 |
| LENGTH | char_length(str) | 支持 length(string A) | 返回字符串长度。Hive 2.2.0 起还有 character_length(简写 char_length)返回 UTF-8 字符数,octet_length 返回字节数。 |
| MAX_BY | max_by(x, y) | 需改写 ROW_NUMBER() OVER (PARTITION BY ... ORDER BY y DESC) = 1 | 函数手册中没有 MAX_BY,用窗口函数取每组第一行。 |
| MONTHS_BETWEEN | months_diff(expr1, expr2) | 支持 months_between(date1, date2) | Hive 1.2.0 起提供。同一天或都是月末时返回整数,否则按 31 天折算并考虑时间部分,结果保留 8 位小数。 |
| NVL | IFNULL(expr1, expr2) | 支持 NVL(value, default_value) | Hive 0.11 起提供。 |
| SIZE | array_length(arr) / map_size(m) | 支持 size(array_or_map) | 同一个函数可以处理 ARRAY 和 MAP,返回 INT。 |
| SORT_ARRAY | array_sort(array) | 支持 sort_array(Array<T>) | Hive 0.9.0 起提供,只能升序。 |
| SPLIT_PART | split_part(content, delimiter, field) | 需改写 split(str, pat)[n - 1] | 内置函数中没有 SPLIT_PART。split 的第二个参数是正则表达式,返回数组,数组下标从 0 开始。 |
| TO_DATE | str_to_date(str, format) | 需改写 to_date(from_unixtime(unix_timestamp(str, pattern))) | Hive 的 to_date 只返回时间戳字符串的日期部分,没有格式参数。返回类型在 Hive 2.1.0 之前是 string,之后是 date。 |
| WM_CONCAT | GROUP_CONCAT([DISTINCT] expr [ORDER BY ...] [SEPARATOR sep]) | 需改写 concat_ws(',', collect_list(col)) | 函数手册中没有 WM_CONCAT,用 concat_ws 拼接 collect_list 的结果,顺序不固定。 |
迁移注意事项
APPROX_COUNT_DISTINCT 近似去重计数
- 改写成 Hive 或 Flink 的 COUNT(DISTINCT) 后结果是精确值,但资源消耗会明显变大,大数据量下要评估内存和运行时间。
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 元素。
DATEADD 按单位加减日期
- MaxCompute 按月加减时,如果目标月份没有对应日期,结果取当月最后一天。StarRocks 的 DATE_ADD 遇到不存在的日期返回 NULL。
DATETRUNC 日期截断
- 参数顺序不同:MaxCompute 是日期在前,Hologres、StarRocks 和 Spark 是单位在前,Doris 两种都接受。
- Hive 的 trunc 只能截断到月和年,按周、按季度汇总需要自己计算。
DAYOFWEEK 星期几
- Hive 的内置函数文档没有 dayofweek,只能用 Hive 2.2.0 起提供的 extract(dayofweek FROM ...)。
EXPLODE 数组展开为多行
- 空数组和 NULL 数组的行会被直接丢掉:MaxCompute、Doris 的 EXPLODE 和 StarRocks 的 UNNEST 都是这样。需要保留时,Doris 和 Spark 用 EXPLODE_OUTER,StarRocks 3.2.7 起用 LEFT JOIN UNNEST(...) ON TRUE。
- 需要元素位置时,Hive 和 Spark 的 posexplode 位置从 0 开始,Flink 的 WITH ORDINALITY 从 1 开始,迁移时要调整下标。
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。
GETDATE 获取当前时间
- 返回类型不同:MaxCompute、StarRocks 和 Doris 返回 DATETIME,Hologres 的 NOW 带时区(文档把不带时区的版本单独列为 LOCALTIMESTAMP),Flink 返回 TIMESTAMP_LTZ(3)。直接写入字符串或 DATETIME 字段时,格式可能变化。
- 精度不同:MaxCompute 默认到秒,StarRocks 和 Doris 默认到秒、可传参数到微秒,Flink 到毫秒。用当前时间做去重或比较时要注意小数部分。
- Hive 和 Spark 的 current_timestamp 可以不带括号,Doris 文档中的写法是 current_timestamp()。迁移时统一写 NOW() 更容易对齐。
LENGTH 字符串长度
- StarRocks 和 Doris 的 LENGTH 返回字节数。像 WHERE LENGTH(name) > 10 这样的条件,迁移后对中文内容会多筛出很多行,而且不会报错。
- 按字符计数统一写 CHAR_LENGTH 最稳妥:Hologres、StarRocks、Doris、Flink 都支持,Hive 2.2.0 起也支持(char_length 是 character_length 的简写)。
MAX_BY 取最大值对应的列
- 并列最大时结果不确定:MaxCompute 随机返回一行,StarRocks 返回最先遇到的一行。需要稳定结果时,改用 ROW_NUMBER 并在 ORDER BY 中加上唯一的次排序列。
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 元素也计入个数。需要只统计非空元素时,要先过滤再计数。
SORT_ARRAY 数组排序
- Spark 有两个排序函数:sort_array 升序时把 NULL 放在开头,array_sort 把 NULL 放在末尾。从 MaxCompute 或 Hive 迁移时应使用 sort_array,结果才一致。
- 降序的写法不同:MaxCompute 和 Spark 传第二个参数,Flink 传 ascending_order,Doris 用 ARRAY_REVERSE_SORT,Hive 和 Hologres 的函数只能升序。
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,不能这样写。
TO_DATE 字符串转日期
- 同名不同义:把 MaxCompute 的 TO_DATE('20261013', 'yyyymmdd') 直接搬到 StarRocks、Doris 或 Hive 会报错或得到错误结果,需要改用 str_to_date 或 unix_timestamp。
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 关键字声明分隔符。
可以直接用的函数
下面 25 个函数在两个引擎中写法相同。参数、返回值和边界情况仍可能不同,点开函数页查看细节。
- ADD_MONTHS 按月加减
- ARRAY_CONTAINS 判断数组是否包含元素
- COALESCE 取第一个非空值
- CONCAT 字符串拼接
- CONCAT_WS 按分隔符拼接
- DATE_ADD 日期加减
- DATE_FORMAT 日期格式化
- DATE_SUB 日期减天数
- DATEDIFF 日期差
- DECODE 多值匹配
- FROM_UNIXTIME 时间戳转日期
- GET_JSON_OBJECT 提取 JSON 字段
- IF 条件判断
- INSTR 查找子串位置
- LAST_DAY 当月最后一天
- PERCENTILE_APPROX 近似分位数
- REGEXP_EXTRACT 正则提取
- REGEXP_REPLACE 正则替换
- SPLIT 字符串拆分
- STR_TO_MAP 字符串转 Map
- SUBSTR 截取子串
- SUBSTRING_INDEX 按分隔符截取
- TO_CHAR 日期转字符串
- UNIX_TIMESTAMP 日期转时间戳
- WEEKOFYEAR 一年中的第几周