有没有一种方法可以对 DATE 类型的值进行日期算术运算,而结果不是 TIMESTAMP 类型?

Is there a way to do date arithmetic on values of type DATE without result being of type TIMESTAMP?

假设我正在做类似的查询(其中 due_datedate 类型):

SELECT
       (due_date + (7 * INTERVAL '1 DAY')) AS due_date_mod
FROM test_table

结果 due_date_mod 是类型 timestamp

这是有道理的,因为操作的结果应该是一种类型,无论具体值如何,间隔可以有 hours/minutes/seconds。
但是有没有一种方法可以将 days/months/years 添加到日期,而结果不是时间戳,而且显然也没有强制转换?还是铸造是唯一的方法?

我知道我可以使用以下方式增加天数:

SELECT
       (due_date + INTEGER '7') AS due_date_mod

结果是类型date
但是我可以做类似的事情几个月或几年吗(不把它们转换成几天)?

编辑: 似乎没有满足问题要求的解决方案。获得所需结果的正确方法在标记的答案中。

您已经发现可以将integer加到date来增加天数,返回date:

SELECT due_date + 7 AS due_date_mod  -- type date
FROM   test_table;

(因为date里面是一个整数,所以加上integer是非常简单和便宜的。)

如您在 table Date/Time Operators in the manual, there is no other operator that would return date (and no function 中所见。

并且单位“月”必须相对于左操作数进行解释(因为月份的天数不同)。所以你不能简单地从你的月份中提取天数。您必须使用 date + interval 才能正确使用。加个演员就可以了,简单又便宜:

SELECT (due_date + interval '3 months')::date AS due_date_mod
FROM   test_table;

你知道 (7 * interval '1 mon') = interval '7 mon',对吧?

最初我误解了这个问题所以下面是@mcc 已经发现的例子(包括输出)。我会把这个答案留在这里,因为它们可能对其他人寻找日期、时间戳和间隔算术的例子有用。

date 添加到间隔:

select '2021-08-11 12:23:00'::date + '2 months'::interval;
      ?column?       
---------------------
 2021-09-11 00:00:00

或者,如果该字段是 timestamp,您可以将其转换为 date,但您仍然会得到 datetime 答案:

select ('2021-08-11 12:23:00'::timestamp)::date + '2 years'::interval;
      ?column?       
---------------------
 2023-08-11 00:00:00

如上面的示例所示,将 interval 添加到 datetimestamp 时,结果始终是 timestamp。如果您要求结果是一个日期,您可以在添加 interval:

之后进行转换
select ('2021-08-11 12:23:00'::timestamp + '60 days'::interval)::date;
    date    
------------
 2021-10-10

我使用天、月和年的间隔来演示如何添加每个时间段。