首页 / 日期
ADD_MONTHS 按月加减
ADD_MONTHS 给日期加上若干个月。月末日期是主要差异点:1 月 31 日加一个月,StarRocks、Doris 和 Spark 返回 2 月最后一天。返回类型也不同,MaxCompute 返回字符串,StarRocks 返回 DATETIME。
各引擎写法
| 引擎 | 支持 | 写法 | 说明 | 依据 |
|---|---|---|---|---|
| MaxCompute | 支持 | ADD_MONTHS(startdate, num_months) |
返回 yyyy-mm-dd 格式的 STRING,不是 DATE。格式不对时返回 NULL,例如 '20170214'。 | 官方文档 |
| Hologres | 需改写 | d + interval '1 month' |
ADD_MONTHS 是 Oracle 兼容函数,需要先加载 orafce 扩展。原生写法用 interval 加减。 | 官方文档 |
| StarRocks | 支持 | add_months(date, months) |
返回 DATETIME,DATE 输入也会转成 DATETIME。目标月份没有对应日期时返回当月最后一天,例如 2022-01-31 加 1 个月得到 2022-02-28。 | 官方文档 |
| Doris | 需改写 | MONTHS_ADD(date, nums) |
文档没有列出 ADD_MONTHS 别名。返回类型与输入相同,2020-01-31 加 1 个月得到 2020-02-29。 | 官方文档 |
| Hive | 支持 | add_months(start_date, num_months[, output_date_format]) |
Hive 1.1.0 起提供,返回 string。Hive 4.0.0 之前会忽略时间部分,4.0.0 起可以指定输出格式。 | 官方文档 |
| Spark SQL | 支持 | add_months(start_date, num_months) |
Spark 1.5.0 起提供。add_months('2016-08-31', 1) 返回 2016-09-30。 | 官方文档 |
| Flink SQL | 需改写 | TIMESTAMPADD(MONTH, n, timepoint) |
内置函数中没有 ADD_MONTHS,用 TIMESTAMPADD 的 MONTH 单位。 | 官方文档 |
迁移注意事项
- 月末日期:StarRocks、Doris 和 Spark 在目标月份没有对应日期时取当月最后一天。StarRocks 文档特别说明,2022-02-28 加 1 个月得到 3 月 28 日而不是 3 月 31 日,这和 Oracle 的行为不同。
- MaxCompute 返回字符串,Hive 4.0.0 之前也会丢掉时间部分。结果和 DATE 或 DATETIME 字段比较时,注意类型转换。
- Hologres 和 Flink 的月末行为文档没有写明,迁移涉及月末日期时建议用已知数据核对。
示例
计算合同到期日(签约日加 12 个月)
SELECT ADD_MONTHS(sign_date, 12) FROM contracts;SELECT sign_date + interval '12 month' FROM contracts;SELECT add_months(sign_date, 12) FROM contracts;SELECT MONTHS_ADD(sign_date, 12) FROM contracts;SELECT TIMESTAMPADD(MONTH, 12, sign_time) FROM contracts;