Sql 从datetime提取日期并从duration计算总分钟数

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

我在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-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