如何结束一天的工作?
Posted
技术标签:
【中文标题】如何结束一天的工作?【英文标题】:How to get the end of a day? 【发布时间】:2015-02-25 16:04:26 【问题描述】:我正在使用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
也就是说,每个日期都将设置为一天的结束。
【问题讨论】:
【参考方案1】:很多方法。
在我的示例中使用列名 "ts"。 timestamp
列的“日期”会产生误导。
1.
转换为date
。 (这里我们需要 date
类型。在其他表达式中,date_trunc()
也一样。)。然后在减去区间1 second
之前加上1
(integer
):
SELECT ts::date + 1 - interval '1 sec' AS last_sec_of_day
2.
添加一个单个间隔'1 day - 1 sec'
。不需要两个操作,Postgres interval input 允许单个表达式。
SELECT ts::date + interval '1 day - 1 sec' AS last_sec_of_day
3.
更简单,将所需的时间组件添加到日期:
SELECT ts::date + time '23:59:59' AS last_sec_of_day
4.
但是, 不是“一天的结束”。 Postgres xxxx-xx-xx 23:59:59
timestamp
data type(目前,但不太可能更改)以微秒级分辨率存储值。
一天中可能的最新时间戳是xxxx-xx-xx 23:59:59.999999
:
SELECT ts::date + interval '1 day - 1 microsecond' AS last_ts_of_day
5.
等效:
SELECT ts::date + time '23:59:59.999999' AS last_ts_of_day -- or interval
最后一个表达式应该是除了正确之外最快的。
6.
然而,更好的方法通常是以第二天的开始作为唯一的上限,它不依赖于实现细节,甚至更简单生成:
SELECT ts::date + 1 AS next_day
7.
第二天的实际第一个时间戳:
SELECT date_trunc('day', ts) + interval '1 day' AS next_day_1st_ts
至少从 Postgres 8.4 开始,所有版本都可以工作。 Postgres 13 中的演示:
db小提琴here
【讨论】:
【参考方案2】:取日期,截断,加一日减一秒:
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'
但这似乎不太优雅。
【讨论】:
只是补充一点,如果你想要精确到毫秒,你可以用 'millisecond' 替换 'second' 部分,最后是 'xxxx-xx-xx 23:59:59.999'。跨度> 我喜欢select the_date::date + interval '1 day - 1 second';
另外,不要用保留字来命名列。以上是关于如何结束一天的工作?的主要内容,如果未能解决你的问题,请参考以下文章
如何在javascript中获取指定时区的一天的开始时间和结束时间?