有没有一种方法可以对 DATE 类型的值进行日期算术运算,而结果不是 TIMESTAMP 类型?
Is there a way to do date arithmetic on values of type DATE without result being of type TIMESTAMP?
假设我正在做类似的查询(其中 due_date
是 date
类型):
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
添加到 date
或 timestamp
时,结果始终是 timestamp
。如果您要求结果是一个日期,您可以在添加 interval
:
之后进行转换
select ('2021-08-11 12:23:00'::timestamp + '60 days'::interval)::date;
date
------------
2021-10-10
我使用天、月和年的间隔来演示如何添加每个时间段。
假设我正在做类似的查询(其中 due_date
是 date
类型):
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
添加到 date
或 timestamp
时,结果始终是 timestamp
。如果您要求结果是一个日期,您可以在添加 interval
:
select ('2021-08-11 12:23:00'::timestamp + '60 days'::interval)::date;
date
------------
2021-10-10
我使用天、月和年的间隔来演示如何添加每个时间段。