SQL 方言通

首页 / 工具 / 迁移清单 / Spark SQL → Hologres

Spark SQL 迁移到 Hologres 的函数改写清单

从 Spark SQL 迁移到 Hologres 时,在 Spark SQL 有对应写法的 44 个常用函数中,27 个需要改写(其中 2 个在 Hologres 没有对应函数)。逐个列出两边写法和注意事项。

需要改写的函数 · 迁移注意事项 · 可以直接用的函数 · 反向:Hologres 迁移到 Spark SQL

需要改写的函数

函数Spark SQL 写法Hologres 写法Hologres 说明
ADD_MONTHSadd_months(start_date, num_months)需改写 d + interval '1 month'ADD_MONTHS 是 Oracle 兼容函数,需要先加载 orafce 扩展。原生写法用 interval 加减。
ANY_VALUEany_value(expr[, isIgnoreNull])需改写 MAX(col)通用聚合函数中没有 ANY_VALUE。组内值都相同时,可以用 MAX 或 MIN 代替。
COLLECT_LISTcollect_list(expr)需改写 ARRAY_AGG(expression)没有 COLLECT_LIST,用 ARRAY_AGG。
COLLECT_SETcollect_set(expr)需改写 ARRAY_AGG(DISTINCT expression)没有 COLLECT_SET,用 ARRAY_AGG。不支持 JSON、JSONB、INTERVAL 和数组等类型。
DATE_ADDdate_add(start_date, num_days)需改写 DATEADD(d, num, 'day')文档中没有 DATE_ADD,可以用 DATEADD 或 d + interval。DATEADD 需要 V2.0.31~V2.1.0 或 V2.1.13 及以上版本。
DATE_FORMATdate_format(timestamp, fmt)需改写 TO_CHAR(timestamp, 'YYYY-MM-DD HH24:MI:SS')文档中没有 DATE_FORMAT,用 TO_CHAR 代替。格式符是 PostgreSQL 风格,HH 默认是 12 小时制,24 小时制要写 HH24。
DATE_SUBdate_sub(start_date, num_days)需改写 d - interval '1 day'文档中没有 DATE_SUB。可以用日期减 interval,也可以写 DATEADD(d, -n, 'dd')。DATEADD 需要 V2.0.31~V2.1.0 或 V2.1.13 及以上版本。
DATEADDts + INTERVAL n HOUR支持 DATEADD(d, num, str)需要 V2.0.31~V2.1.0 或 V2.1.13 及以上版本。单位写法与 MaxCompute 一致,包括 yyyy、mm、dd、hh、mi、ss。默认只支持 1925~2282 年,并且暂不支持常量入参写入。
DAYOFWEEKdayofweek(date)需改写 EXTRACT(DOW FROM ts) + 1DOW 以周日为 0,所以要加 1 才和其他引擎一致。ISODOW 以周一为 1、周日为 7。
DECODEdecode(expr, search, result [, search, result ] ... [, default])需改写 CASE expr WHEN search THEN result ... ELSE default END条件函数文档中没有 DECODE,用 CASE 改写。
EXPLODEexplode(expr)需改写 UNNEST(anyarray)把数组的每个元素展开成一行。
FROM_JSONfrom_json(jsonStr, schema[, options])需改写 json_str::jsonb ->> 'key'没有 FROM_JSON。先转成 JSON 或 JSONB,再用 -> 或 ->> 取字段,->> 返回 TEXT。需要展开成多列时可以用 json_populate_record。
FROM_UNIXTIMEfrom_unixtime(unix_time[, fmt])需改写 TO_TIMESTAMP(seconds)文档中没有 FROM_UNIXTIME。TO_TIMESTAMP(double precision) 按秒转换,返回 TIMESTAMPTZ。需要字符串时再用 TO_CHAR。
GETDATEcurrent_timestamp() 或 now()别名 NOW() 或 CURRENT_TIMESTAMP返回当前事务的开始时刻,NOW、CURRENT_TIMESTAMP 和 TRANSACTION_TIMESTAMP 等效。需要每次调用都取实时时刻时用 CLOCK_TIMESTAMP。
INSTRinstr(str, substr)需改写 STRPOS(str, substr)INSTR 是 Oracle 兼容函数,需要先安装 orafce 扩展才能用,支持起始位置和第 N 次出现。不装扩展时用 STRPOS。
MONTHS_BETWEENmonths_between(timestamp1, timestamp2[, roundOff])需改写 (EXTRACT(YEAR FROM a) - EXTRACT(YEAR FROM b)) * 12 + EXTRACT(MONTH FROM a) - EXTRACT(MONTH FROM b)日期函数中没有 MONTHS_BETWEEN,可以用 EXTRACT 取年和月计算整数月差,不含小数部分。
NVLnvl(expr1, expr2)需改写 COALESCE(value, default_value)条件函数文档中没有 NVL,只有 COALESCE、IF、NULLIF 等,需要改写为 COALESCE。
PERCENTILE_APPROXpercentile_approx(col, percentage[, accuracy])需改写 APPROX_PERCENTILE(p) WITHIN GROUP (ORDER BY col)Hologres V3.1 起提供,用蓄水池抽样计算,最多保留 8,192 个元素。p 是 0~1 之间的常量。
REGEXP_EXTRACTregexp_extract(str, regexp[, idx])需改写 (REGEXP_MATCH(str, pattern))[n]字符串函数中没有 REGEXP_EXTRACT。REGEXP_MATCH 返回由各分组组成的数组,再用数组下标取第 n 组,下标从 1 开始。
SIZEsize(expr)需改写 ARRAY_LENGTH(arr, 1)第二个参数是维度,从 1 开始,一维数组传 1。数组函数文档只覆盖 ARRAY。
SORT_ARRAYsort_array(array[, ascendingOrder])需改写 ARRAY_SORT(anyarray)只有升序。V1.1.46 起支持 TEXT 数组,但会先转成 INT8 再排序;V1.3.18 起 TEXT 数组按字典序排序,并支持 INT4、INT8、FLOAT4、FLOAT8 和 BOOLEAN 数组。
SPLITsplit(str, regex[, limit])需改写 REGEXP_SPLIT_TO_ARRAY(str, pattern)字符串函数中没有 SPLIT。拆成数组用 REGEXP_SPLIT_TO_ARRAY,只取第 n 段用 SPLIT_PART(str, delimiter, n)。
STR_TO_MAPstr_to_map(text[, pairDelim[, keyValueDelim]])不支持 字符串函数中没有 STR_TO_MAP。
SUBSTRsubstr(str, pos[, len])需改写 SUBSTRING(str FROM start FOR len)SUBSTR 是 Oracle 兼容函数,需要先加载 orafce 扩展。PostgreSQL 标准写法是 SUBSTRING。
SUBSTRING_INDEXsubstring_index(str, delim, count)不支持 字符串函数中没有 SUBSTRING_INDEX。只取某一段时可以用 SPLIT_PART。
UNIX_TIMESTAMPunix_timestamp([timeExp[, fmt]])需改写 EXTRACT(EPOCH FROM ts)日期函数中没有 UNIX_TIMESTAMP。EXTRACT 的 epoch 字段返回秒数,类型是 DOUBLE PRECISION。
WEEKOFYEARweekofyear(date)需改写 EXTRACT(WEEK FROM ts)也可以用 week_iso(ts),文档说明语义与 EXTRACT(WEEK FROM ts) 相同、性能更好。返回 DOUBLE PRECISION。

迁移注意事项

以下内容摘自各函数页中提到 Spark SQL 或 Hologres 的注意事项。

ADD_MONTHS 按月加减

ANY_VALUE 取组内任意值

DATE_FORMAT 日期格式化

DATEADD 按单位加减日期

DAYOFWEEK 星期几

DECODE 多值匹配

EXPLODE 数组展开为多行

FROM_UNIXTIME 时间戳转日期

GETDATE 获取当前时间

INSTR 查找子串位置

MONTHS_BETWEEN 相差月数

NVL 空值替换

PERCENTILE_APPROX 近似分位数

REGEXP_EXTRACT 正则提取

SIZE 数组和 Map 元素个数

SORT_ARRAY 数组排序

SPLIT 字符串拆分

STR_TO_MAP 字符串转 Map

SUBSTR 截取子串

SUBSTRING_INDEX 按分隔符截取

UNIX_TIMESTAMP 日期转时间戳

WEEKOFYEAR 一年中的第几周

可以直接用的函数

下面 17 个函数在两个引擎中写法相同。参数、返回值和边界情况仍可能不同,点开函数页查看细节。

相关页面:Spark SQL 函数写法 · Hologres 函数写法 · 全部迁移清单 · 用 SQL 迁移检查器检查自己的 SQL