【问题标题】:Postgresql: How to find hours between 2 dates and 2 times?Postgresql:如何查找 2 个日期和 2 个时间之间的小时数?
【发布时间】:2016-05-04 11:27:00
【问题描述】:

PostgreSQL 9.1

我正在尝试使用查询来查找时间表系统的 2 个日期和 2 次之间的小数/小数小时差异。我正在使用查询来确保软件(不是我编写的)没有任何错误。以下是我正在使用的表中的字段:startdate 是 Date 字段,starttime 是 Time 字段,enddate 是 Date 字段,endtime 是 Time 字段。

我查看了date time docs for 9.1,但仍然没有找到我需要的东西。

  • age() 需要 2 个时间戳,并且似乎给出了整数天的差异,而不是小数天数。我认为不可能将 age() 的结果乘以 24 来获得小时数。我也不知道如何在 age() 函数中包含时间。
  • 我找不到将日期和时间转换为其他内容以使用其他功能的方法。
  • 我搜索了 Google 和 Stackoverflow,但没有找到可以帮助我的信息。我断断续续地花了大约 4 周时间。所以可能已经30个小时了。
  • 注意:我认为我不能添加用户定义的函数。我没有权限。

示例数据:

  • 开始日期和时间:“2016-04-29”和“23:00:00”
  • 结束日期和时间:“2016-04-30”和“01:30:00”

我也试过这个 sql 语句。

SELECT employeetime.dcmasterid as empid, 
       nonchargeabletime.startdate as ncsdate, 
       nonchargeabletime.starttime as ncstime, 
       nonchargeabletime.enddate as ncedate, 
       nonchargeabletime.endtime as ncetime, 
       employeetime.dchours as normhrs, 
       (timestamp (startdate || ' ' || starttime) - timestamp (enddate || ' ' || endtime)) as diffhrs  
FROM employeetime, nonchargeabletime 
WHERE (nonchargeabletime.employeetime=employeetime.dcautoinc) 
       AND  (nonchargeabletime.startdate >= '2016-04-24') 
       AND (nonchargeabletime.startdate <= '2016-04-30') 
       AND (employeetime.dcmasterid IN ('BLURG')) 
       AND (nonchargeabletime.nonchargeabletype=10) 
ORDER BY employeetime.dcmasterid, nonchargeabletime.startdate, nonchargeabletime.starttime;

但我在startdate 收到语法错误,上面写着(timestamp (startdate ||

任何人有任何线索如何做到这一点?

谢谢。

【问题讨论】:

  • 你为什么不使用单个timestamp 列?
  • 我没有设计数据库。这就是供应商所做的。这主要是一个黑盒系统。我获得对数据库的读取权限这一事实本身就是一个小奇迹。
  • 并且:您不需要字符串连接来组合日期+时间:(z.startdate+z.starttime)::timestamp 将为您提供组合值 @a_horse_with_no_name:好的!
  • @wildplasser:你甚至不需要演员表:(enddate + endtime) - (startdate + starttime) 将返回 interval
  • @wildplasser:谢谢。我的计算字段“diffhrs”现在以这种格式返回小时和分钟:08:50:00。如何将其转换为十进制小时?是否有一个函数可以将其转换为十进制小时数?

标签: postgresql date datetime postgresql-9.1


【解决方案1】:

time 添加到date 会生成timestamp,从另一个时间戳中减去一个时间戳会返回interval

所以你需要做的就是:

(enddate + endtime) - (startdate + starttime) as diff

interval 在 SQL 上下文中很好用,但在编程语言中通常更难处理。您可以使用extract(epoch from interval) 轻松地将interval 转换为秒

如果要将其转换为小时,请使用 extract 并除以 3600

extract(epoch from (enddate + endtime) - (startdate + starttime))/3600 as diff_hours

【讨论】:

  • 做到了!谢谢!但是我需要交换开头和结尾,否则答案是否定的。 extract(epoch from (enddate + endtime) - (startdate + starttime))/3600 as diff_hours. 哎呀,我没有及时刷新页面,你已经得到了那个变化。
【解决方案2】:

因为你没有字符串,所以不能使用 ||运算符,但您可以添加时间到日期 (http://www.postgresql.org/docs/9.1/static/functions-datetime.html)。

这应该可以工作(如果你想要整数小时,你可以计算结果):

postgres=# create temporary table ts (startdate date, starttime time, enddate date, endtime time);
CREATE TABLE
postgres=# insert into ts values('2016-05-03', '11:45:15', '2016-05-04', '13:55:43');
INSERT 0 1
postgres=# SELECT startdate,starttime,enddate,endtime, (enddate+endtime)-(startdate+starttime) as interval from ts;
 startdate  | starttime |  enddate   | endtime  |    interval    
------------+-----------+------------+----------+----------------
 2016-05-03 | 11:45:15  | 2016-05-04 | 13:55:43 | 1 day 02:10:28
(1 row)

postgres=# SELECT startdate,starttime,enddate,endtime, EXTRACT(epoch FROM ((enddate+endtime)-(startdate+starttime)))/3600 as hours from ts;
 startdate  | starttime |  enddate   | endtime  |      hours       
------------+-----------+------------+----------+------------------
 2016-05-03 | 11:45:15  | 2016-05-04 | 13:55:43 | 26.1744444444444
(1 row)

【讨论】:

    【解决方案3】:
    WITH zooi(startdate,starttime, enddate,endtime) AS (
        VALUES('2016-04-29'::date , '23:00:00'::time
            ,'2016-04-30'::date , '01:30:00'::time )
            )
    , stamps (sta, sto) AS (
            select (z.startdate+z.starttime)::timestamp
            , (z.enddate+z.endtime)::timestamp
            FROM zooi z
            )
    SELECT sta,sto
            , age(sto,sta) AS how_old
            , (sto-sta)::time AS diff
    FROM stamps;
    

    下一步是将时间(或间隔)结果转换为天或小时。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-12-15
      • 1970-01-01
      • 2023-03-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多