我正在用Postgres(PL/pgSQL)开发一个算法,我需要计算两个时间戳之间的工作时间,考虑到周末不工作,其余的日子只计算从上午8点到下午15点。
示例:
- 从12月3日下午14点到12月4日上午9点应计为2小时:
3rd = 1, 4th = 1
- 从12月3日下午15点到12月7日上午8点应计为8小时:
3rd = 0, 4th = 8, 5th = 0, 6th = 0, 7th = 0
考虑小时分数也是很好的。
我正在用Postgres(PL/pgSQL)开发一个算法,我需要计算两个时间戳之间的工作时间,考虑到周末不工作,其余的日子只计算从上午8点到下午15点。
示例:
3rd = 1, 4th = 1
3rd = 0, 4th = 8, 5th = 0, 6th = 0, 7th = 0
考虑小时分数也是很好的。
3条答案
按热度按时间ergxz8rk1#
根据您的问题,***工作时间***为:周一至周五,上午8时至15时。
舍入结果
仅针对两个给定的时间戳
以1小时为单位进行操作。忽略分数,因此不 * 精确 *,但很简单:
generate_series()
在结束时间大于开始时间的情况下生成一行,并在每个 * full * 给定间隔(1小时)生成另一行。此wold计数输入到**中的每个小时。要忽略小时的小数部分,请从结束时间减去1小时。并且不计数14:00之前开始的小时。EXTRACT()
,请使用字段模式**ISODOW
**而不是DOW
来简化表达式。对于星期日,返回7
而不是0
。time
的简单(而且非常便宜)转换可以很容易地确定合格的小时数。对于整个表
质询:
老SQLF
更精准
为了获得更高的精确度,你可以使用更小的时间单位,例如5分钟的时间片:
单位越小 * 成本越高 *。
在PostGres 9.3+中使用
LATERAL
的清洁器结合Postgres 9.3中新的
LATERAL
特性,上面的查询可以写成:1-小时精度:
5-分钟精度:
这具有额外的优点,即不像上述版本那样从结果中排除包含零工作小时的间隔。
关于
LATERAL
的更多信息:精确结果
波茨格雷斯8.4 +
或者,您可以分别处理时间段的开始和结束,以获得精确到微秒的"精确"结果,这会使查询更加复杂,但成本更低且更精确:
老SQLF
采用
tsrange
的Postgres 9.2 +新的量程类型与intersection operator
*
相结合,为精确结果提供了更优雅的解决方案:时间范围仅跨越一天的简单函数:
如果您的范围从不跨越多天,那么您只需要这么做。
否则,使用这个 Package 器函数来处理 * any * interval:
电话:
老SQLF
w41d8nur2#
不如这样:创建一个24 * 7行的小表,一周中每小时一行。
同样地,为其他的每一天添加24行,不管你给出的是哪一年或哪一个月,你马上就会看到,你只需要表示一周中的所有七天。
umuewwlo3#
以下函数将获取
一天的工作开始时间
一天的工作结束时间
开始时间
结束时间
这将只给予开始日期时间和结束日期时间之间以秒为单位的工作时间差