SQL 方言通

首页 / 日期

MONTHS_BETWEEN 相差月数

MONTHS_BETWEEN(end, start) 返回两个日期相差的月数,带小数。MaxCompute、Doris、Hive 和 Spark 同名可用,小数部分都按每月 31 天折算,但对时间部分和舍入的处理不同。StarRocks 的 months_diff 和 Flink 的 TIMESTAMPDIFF 只返回整数月,Flink 的参数顺序还是反的。

各引擎写法 · 迁移注意事项 · 示例

各引擎写法

引擎支持写法说明依据
MaxCompute支持MONTHS_BETWEEN(end_date, start_date)返回 DOUBLE,end_date 晚于 start_date 时为正。两个日期都是月末时返回整数,否则按天数差除以 31 折算。官方文档
Hologres需改写(EXTRACT(YEAR FROM a) - EXTRACT(YEAR FROM b)) * 12 + EXTRACT(MONTH FROM a) - EXTRACT(MONTH FROM b)日期函数中没有 MONTHS_BETWEEN,可以用 EXTRACT 取年和月计算整数月差,不含小数部分。官方文档
StarRocks需改写months_diff(expr1, expr2)函数列表中没有 MONTHS_BETWEEN。months_diff 返回 expr1 减 expr2 的月数,类型是 BIGINT,只精确到月;日期不存在时返回 NULL。官方文档
Doris支持MONTHS_BETWEEN(end, start[, round_type])与 Oracle 的 MONTHS_BETWEEN 一致。时间部分不参与计算;两个日期同为月末或日相同时返回整数。round_type 为 true 时保留 8 位小数。官方文档
Hive支持months_between(date1, date2)Hive 1.2.0 起提供。同一天或都是月末时返回整数,否则按 31 天折算并考虑时间部分,结果保留 8 位小数。官方文档
Spark SQL支持months_between(timestamp1, timestamp2[, roundOff])Spark 1.5.0 起提供。同一天或都是月末时忽略时间部分,否则按每月 31 天计算,默认保留 8 位小数,roundOff 为 false 时不舍入。官方文档
Flink SQL需改写TIMESTAMPDIFF(MONTH, start, end)没有 MONTHS_BETWEEN。TIMESTAMPDIFF 返回 timepoint2 减 timepoint1 的整数,参数顺序与 MONTHS_BETWEEN 相反。官方文档

迁移注意事项

示例

计算用户注册至今的月数

MaxCompute
SELECT user_id, MONTHS_BETWEEN(GETDATE(), register_time) AS months FROM users;
Hologres
SELECT user_id, (EXTRACT(YEAR FROM NOW()) - EXTRACT(YEAR FROM register_time)) * 12 + EXTRACT(MONTH FROM NOW()) - EXTRACT(MONTH FROM register_time) AS months FROM users;
StarRocks
SELECT user_id, months_diff(NOW(), register_time) AS months FROM users;
Doris
SELECT user_id, MONTHS_BETWEEN(NOW(), register_time) AS months FROM users;
Hive
SELECT user_id, months_between(current_timestamp, register_time) AS months FROM users;
Spark SQL
SELECT user_id, months_between(current_timestamp(), register_time) AS months FROM users;
Flink SQL
SELECT user_id, TIMESTAMPDIFF(MONTH, register_time, CURRENT_TIMESTAMP) AS months FROM users;

同类函数

最后核对日期: