SQL 方言通

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

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

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

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

需要改写的函数

函数Spark SQL 写法Flink SQL 写法Flink SQL 说明
ADD_MONTHSadd_months(start_date, num_months)需改写 TIMESTAMPADD(MONTH, n, timepoint)内置函数中没有 ADD_MONTHS,用 TIMESTAMPADD 的 MONTH 单位。
ANY_VALUEany_value(expr[, isIgnoreNull])需改写 FIRST_VALUE(expression)内置函数中没有 ANY_VALUE,可以用聚合函数 FIRST_VALUE 代替。
APPROX_COUNT_DISTINCTapprox_count_distinct(expr[, relativeSD])需改写 COUNT(DISTINCT expr)内置函数文档中没有近似去重函数,只能用精确的 COUNT(DISTINCT)。
COLLECT_LISTcollect_list(expr)需改写 ARRAY_AGG(expression)没有输入行时返回 NULL,可以用 RESPECT NULLS 或 IGNORE NULLS 控制是否保留 NULL。
COLLECT_SETcollect_set(expr)需改写 ARRAY_AGG(DISTINCT expression)也可以用 COLLECT(DISTINCT expression),返回的是 MULTISET 而不是数组。
DATE_ADDdate_add(start_date, num_days)需改写 TIMESTAMPADD(DAY, n, timepoint)内置函数中没有 DATE_ADD,改用 TIMESTAMPADD。
DATE_SUBdate_sub(start_date, num_days)需改写 TIMESTAMPADD(DAY, -n, timepoint)内置函数中没有 DATE_SUB,用 TIMESTAMPADD 传负数。
DATEADDts + INTERVAL n HOUR需改写 TIMESTAMPADD(unit, n, timepoint)单位可以是 SECOND、MINUTE、HOUR、DAY、WEEK、MONTH、QUARTER 或 YEAR。
DATEDIFFdatediff(endDate, startDate)需改写 TIMESTAMPDIFF(DAY, timepoint1, timepoint2)内置函数中没有 DATEDIFF。TIMESTAMPDIFF 返回 timepoint1 与 timepoint2 之间带符号的单位数,先写单位,再写开始时间和结束时间。
DATETRUNCdate_trunc('MONTH', ts)需改写 FLOOR(timepoint TO MONTH)内置函数中没有 DATE_TRUNC,用 FLOOR ... TO 向下取整到指定单位。
DECODEdecode(expr, search, result [, search, result ] ... [, default])需改写 CASE expr WHEN search THEN result ... ELSE default ENDDECODE(binary, string) 是按字符集解码二进制,不能做多值匹配,需要用 CASE 改写。
EXPLODEexplode(expr)需改写 CROSS JOIN UNNEST(arr) AS t(x)内置函数中没有 EXPLODE,数组展开写在 JOIN 中:CROSS JOIN UNNEST,也支持 LEFT JOIN。需要元素位置时加 WITH ORDINALITY,位置从 1 开始,目前只支持 CROSS JOIN。也可以展开 map 和 multiset。
FROM_JSONfrom_json(jsonStr, schema[, options])需改写 JSON_VALUE(json, path) / JSON_QUERY(json, path)没有 FROM_JSON。JSON_VALUE 取标量值,JSON_QUERY 取对象或数组,返回 JSON 字符串。
GET_JSON_OBJECTget_json_object(json_txt, path)需改写 JSON_VALUE(json, path)提取 JSON 中的标量值,可以用 RETURNING 子句指定返回类型。
GETDATEcurrent_timestamp() 或 now()别名 CURRENT_TIMESTAMP 或 NOW()返回本地时区的 TIMESTAMP_LTZ(3)。流模式下每条记录都会重新求值,批模式下只在查询开始时求值一次。
LAST_DAYlast_day(date)需改写 TIMESTAMPADD(DAY, -1, TIMESTAMPADD(MONTH, 1, FLOOR(ts TO MONTH)))内置函数中没有 LAST_DAY。先用 FLOOR 取当月第一天,加一个月再减一天。
LENGTHlength(expr)别名 CHAR_LENGTH(string)返回字符数,别名 CHARACTER_LENGTH。内置函数中没有 LENGTH。
MAX_BYmax_by(x, y[, k])需改写 ROW_NUMBER() OVER (PARTITION BY ... ORDER BY y DESC) = 1内置函数中没有 MAX_BY 或 ARG_MAX,用 ROW_NUMBER 窗口函数改写。
MONTHS_BETWEENmonths_between(timestamp1, timestamp2[, roundOff])需改写 TIMESTAMPDIFF(MONTH, start, end)没有 MONTHS_BETWEEN。TIMESTAMPDIFF 返回 timepoint2 减 timepoint1 的整数,参数顺序与 MONTHS_BETWEEN 相反。
NVLnvl(expr1, expr2)需改写 IFNULL(input, null_replacement)没有 NVL,可以用 IFNULL 或 COALESCE。
PERCENTILE_APPROXpercentile_approx(col, percentage[, accuracy])需改写 PERCENTILE(expr, percentage[, frequency])PERCENTILE 是精确分位数,按线性插值计算。2.0 起的文档中有这个函数,1.20 的文档中没有,使用前请按所用版本确认。文档提示在普通分组聚合中开销较大,建议用在窗口场景。
SIZEsize(expr)别名 CARDINALITY(array_or_map)数组返回元素个数,Map 返回键值对个数。
SORT_ARRAYsort_array(array[, ascendingOrder])需改写 ARRAY_SORT(array[, ascending_order[, null_first]])默认升序且 NULL 在开头。可以分别指定升降序和 NULL 的位置。任一参数为 NULL 时返回 NULL。
SPLIT_PARTsplit_part(str, delimiter, partNum)需改写 SPLIT_INDEX(str, delimiter, n - 1)下标从 0 开始。下标为负数或任一参数为 NULL 时返回 NULL。
SUBSTRING_INDEXsubstring_index(str, delim, count)不支持 内置函数中没有 SUBSTRING_INDEX。只取某一段时可以用 SPLIT_INDEX,下标从 0 开始。
TO_CHARto_char(expr, format)需改写 DATE_FORMAT(timestamp, 'yyyy-MM-dd HH:mm:ss')没有 TO_CHAR。DATE_FORMAT 的格式符兼容 Java SimpleDateFormat。
WEEKOFYEARweekofyear(date)别名 WEEK(date)返回 1~53,等价于 EXTRACT(WEEK FROM date)。
WM_CONCATstring_agg(expr[, delimiter]) WITHIN GROUP (ORDER BY ...)需改写 LISTAGG(expression[, separator])分隔符写在后面。

迁移注意事项

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

ADD_MONTHS 按月加减

ANY_VALUE 取组内任意值

APPROX_COUNT_DISTINCT 近似去重计数

DATEADD 按单位加减日期

DATEDIFF 日期差

DATETRUNC 日期截断

DECODE 多值匹配

EXPLODE 数组展开为多行

GETDATE 获取当前时间

LENGTH 字符串长度

MONTHS_BETWEEN 相差月数

NVL 空值替换

PERCENTILE_APPROX 近似分位数

SIZE 数组和 Map 元素个数

SORT_ARRAY 数组排序

SPLIT_PART 按分隔符取第 N 段

SUBSTRING_INDEX 按分隔符截取

TO_CHAR 日期转字符串

可以直接用的函数

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

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