Postgresql:如何查找 2 个日期和 2 个时间之间的小时数?
Postgresql: How to find hours between 2 dates and 2 times?
Postgresql9.1
我正在尝试使用查询来查找时间表系统中 2 个日期和 2 个时间之间的 fractional/decimal 小时内的差异。我正在使用查询来确保软件(不是我写的)没有任何错误。以下是我正在使用的 table 中的字段:startdate 是一个 Date 字段,starttime 是一个 Time 字段,enddate 是一个 Date 字段,endtime 是一个 Time 字段。
我已经查看了 date time docs for 9.1,但仍然没有找到我需要的东西。
- age() 需要 2 个时间戳,并且似乎给出整数天数而非小数天数的差异。我认为不可能将 age() 的结果乘以 24 来获得小时数。我也不知道如何将时间包含在 age() 函数中。
- 我找不到将日期和时间转换为其他内容以使用其他功能的方法。
- 我搜索了 Google 和 Whosebug,但没有找到可以帮助我的信息。我断断续续地花了大约 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 ||
。
有人知道怎么做吗?
谢谢。
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;
下一步是将时间(或间隔)结果转换为天或小时。
将 time
添加到 date
会产生 timestamp
并从另一个 returns 中减去一个时间戳会产生 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
因为没有字符串,所以不能使用||运算符,但您可以将时间添加到日期 (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)
Postgresql9.1
我正在尝试使用查询来查找时间表系统中 2 个日期和 2 个时间之间的 fractional/decimal 小时内的差异。我正在使用查询来确保软件(不是我写的)没有任何错误。以下是我正在使用的 table 中的字段:startdate 是一个 Date 字段,starttime 是一个 Time 字段,enddate 是一个 Date 字段,endtime 是一个 Time 字段。
我已经查看了 date time docs for 9.1,但仍然没有找到我需要的东西。
- age() 需要 2 个时间戳,并且似乎给出整数天数而非小数天数的差异。我认为不可能将 age() 的结果乘以 24 来获得小时数。我也不知道如何将时间包含在 age() 函数中。
- 我找不到将日期和时间转换为其他内容以使用其他功能的方法。
- 我搜索了 Google 和 Whosebug,但没有找到可以帮助我的信息。我断断续续地花了大约 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 ||
。
有人知道怎么做吗?
谢谢。
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;
下一步是将时间(或间隔)结果转换为天或小时。
将 time
添加到 date
会产生 timestamp
并从另一个 returns 中减去一个时间戳会产生 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
因为没有字符串,所以不能使用||运算符,但您可以将时间添加到日期 (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)