Sql 从datetime提取日期并从duration计算总分钟数
我在Postgres有一个表,如下所示:Sql 从datetime提取日期并从duration计算总分钟数,sql,postgresql,datetime,Sql,Postgresql,Datetime,我在Postgres有一个表,如下所示: | id | start_time | end_time | duration | |----|--------------------------|--------------------------|----------| | 1 | 2018-05-11T00:00:20.631Z | 2018-05-11T01:03:14.496Z | 1:02:54 | | 2 | 2018-0
| id | start_time | end_time | duration |
|----|--------------------------|--------------------------|----------|
| 1 | 2018-05-11T00:00:20.631Z | 2018-05-11T01:03:14.496Z | 1:02:54 |
| 2 | 2018-05-11T00:00:04.877Z | 2018-05-11T00:00:14.641Z | 0:00:10 |
| 3 | 2018-05-11T01:03:28.063Z | 2018-05-11T01:04:36.410Z | 0:01:08 |
| 4 | 2018-05-11T00:00:20.631Z | 2018-05-11T02:03:14.496Z | 2:02:54 |
| id | start_time | end_time | duration | start | end | duration_minutes |
|----|--------------------------|--------------------------|----------|-----------|-----------|------------------|
| 1 | 2018-05-11T00:00:20.631Z | 2018-05-11T01:03:14.496Z | 1:02:54 | 5/11/2018 | 5/11/2018 | 62 | -- (60+2)
| 2 | 2018-05-11T00:00:04.877Z | 2018-05-11T00:00:14.641Z | 0:00:10 | 5/11/2018 | 5/11/2018 | 0 |
| 3 | 2018-05-11T01:03:28.063Z | 2018-05-11T01:04:36.410Z | 0:01:08 | 5/11/2018 | 5/11/2018 | 1 |
| 4 | 2018-05-11T00:00:20.631Z | 2018-05-11T02:03:14.496Z | 2:02:54 | 5/11/2018 | 5/11/2018 | 122 | -- (2X60 +2)
start\u time
和end\u time
存储为varchar
。格式为“yyyy-mm-dd hh24:mi:ss.ms”(ISO格式)。持续时间
已计算为结束时间-开始时间
。格式为hh:mi:ss
我需要结果表输出,如下所示:
| id | start_time | end_time | duration |
|----|--------------------------|--------------------------|----------|
| 1 | 2018-05-11T00:00:20.631Z | 2018-05-11T01:03:14.496Z | 1:02:54 |
| 2 | 2018-05-11T00:00:04.877Z | 2018-05-11T00:00:14.641Z | 0:00:10 |
| 3 | 2018-05-11T01:03:28.063Z | 2018-05-11T01:04:36.410Z | 0:01:08 |
| 4 | 2018-05-11T00:00:20.631Z | 2018-05-11T02:03:14.496Z | 2:02:54 |
| id | start_time | end_time | duration | start | end | duration_minutes |
|----|--------------------------|--------------------------|----------|-----------|-----------|------------------|
| 1 | 2018-05-11T00:00:20.631Z | 2018-05-11T01:03:14.496Z | 1:02:54 | 5/11/2018 | 5/11/2018 | 62 | -- (60+2)
| 2 | 2018-05-11T00:00:04.877Z | 2018-05-11T00:00:14.641Z | 0:00:10 | 5/11/2018 | 5/11/2018 | 0 |
| 3 | 2018-05-11T01:03:28.063Z | 2018-05-11T01:04:36.410Z | 0:01:08 | 5/11/2018 | 5/11/2018 | 1 |
| 4 | 2018-05-11T00:00:20.631Z | 2018-05-11T02:03:14.496Z | 2:02:54 | 5/11/2018 | 5/11/2018 | 122 | -- (2X60 +2)
start
和end
分别只需要包含mm/dd/yyyy
部分的start\u时间
和end\u时间
duration\u minutes
应以分钟为单位计算总持续时间(例如,如果持续时间为1:02:54,则持续时间以分钟为单位应为62,即60+2)
如何使用SQL执行此操作?以下内容似乎可以满足您的要求:
select v.starttime::timestamp::date, v.endtime::date,
extract(epoch from v.endtime::timestamp - v.starttime::timestamp)/60
from (values ('2018-05-11T00:00:20.631Z', '2018-05-11T01:03:14.496Z')) v(starttime, endtime)
如果希望日期采用特定格式,则使用基于
varchar
输入的to_char()
,此查询将生成所需的结果,确切地说:
SELECT *
, to_char(start_time::timestamp, 'FMMM/DD/YYYY') AS start
, to_char(end_time::timestamp, 'FMMM/DD/YYYY') AS end
, extract(epoch FROM duration::interval)::int / 60 AS duration_minutes
FROM tbl;
要点:
- 使用
和timestamp
而不是interval
作为开头。varchar
或者根本不存储功能相关列
。它可以很便宜地进行动态计算duration
- 用于显示/使用特定的文本表示。
要明确,不要依赖可能在会话之间更改的区域设置。
模式修饰符用于(): 填充模式(抑制前导零和填充空格)FM
生成包含的秒数。要截断小数分钟吗?整数除法就是这样做的,所以转换为提取(间隔的历元)
,如图所示。相关的:int
varchar
在这里不合适。你到底为什么要将时间戳存储为varchar?这真是一个糟糕的主意,一匹没有名字的马:我将把它存储为datetime。Postgres中没有datetime
<代码>时间戳或时间戳
。而duration
可能应该是类型interval
。我们是继续假设varchar
输入还是时间戳
/间隔
?在结果中是否需要T
和Z
装饰符?这些是ISO格式的可选。我不想重新计算持续时间。我只想把它转换成分钟@Erwin Brandstetter:我使用了提取(epoch FROM duration::interval)::int作为持续时间\u秒
并得到秒数。但是我怎样才能得到分数呢milliseconds@Symphony:转换为整数将舍入小数秒。取消强制转换以获得一个最多为6个小数位数的双精度
数字:提取(从持续时间中提取历元::间隔)为秒数_和分数
。但示例中的持续时间已经四舍五入,因此需要重新计算持续时间以获得分数单位。参见:dbfiddle