如何结束一天?

问题描述 投票:0回答:2

我正在使用

PostgreSQL 8.4
。我有表
my_tbl
的一列,其中包含日期(
timestamp without timezone
)。例如:

       date
-------------------
2014-05-27 12:03:20
2014-10-30 01:20:03
2013-10-19 16:34:34
2013-07-10 15:24:26
2013-06-24 18:15:06
2012-07-14 07:09:14
2012-05-13 04:46:18
2013-01-04 21:31:10
2013-03-26 10:17:02

如何编写以以下格式返回所有日期的 SQL 查询:

xxxx-xx-xx 23:59:59

那是每个日期都会被设置为一天的结束。

sql postgresql date-arithmetic
2个回答
32
投票

很多方式。

我们说的是

timestamp
类型。 Postgres 中的首选类型是
timestamptz
。注意区别!参见:

在我的例子中使用列名

ts
。时间戳列的“日期”会产生误导。

同一天的最后一秒

1.

ts::date + 1 - interval '1 sec'

投射到

date
,加
integer '1'
,然后减去
interval '1 second'
.

加法 date + int 是唯一实际需要类型

date
的情况。此答案中的所有其他表达式同样适用于
date_trunc()
- 甚至更快。

2.

ts::date              + interval '1 day - 1 sec'
date_trunc('day', ts) + interval '1 day - 1 sec'

Postgres interval input 允许具有多个时间单位的单个表达式。无需两次操作。

3.

date_trunc('day', ts) + interval '23:59:59'

更简单的是,将所需的时间组件添加到日期(或一天的开始)。

4.

date_trunc('day', ts) + time '23:59:59'

与类型相同

time
.

同一天的最后一个时间戳

xxxx-xx-xx 23:59:59
not“一天结束”。 Postgres
timestamp
数据类型
(目前,不太可能改变)以微秒分辨率存储值。一天的最新可能时间戳是
xxxx-xx-xx 23:59:59.999999
.

5.

date_trunc('day', ts) + interval '1 day - 1 microsecond'

6.

date_trunc('day', ts) + interval '23:59:59.999999'

7.

date_trunc('day', ts) + time '23:59:59.999999'

这最后一个表达式应该是除了正确之外最快.

第二天开始

通常,在第二天开始时作为 exclusive upper bound 操作是更好的方法。不依赖于实现细节,生成起来更简单。

8.

ts::date + 1  -- returns date!

9.

date_trunc('day', ts) + interval '1 day'  -- returns timestamp

至少从 Postgres 8.4 开始,所有版本都可以工作。 Postgres 15 中的演示:

小提琴


22
投票

取日期,截断它,加一天减一秒:

select date_trunc('day', date) + interval '1 day' - interval '1 second'

如果要更改表中的数据,可以将逻辑放在

update
中。

当然也可以加上24*60*60 - 1秒:

select date_trunc('day', date) + (24*60*60 - 1) * interval '1 second'

但这似乎不太优雅。

© www.soinside.com 2019 - 2024. All rights reserved.