PostgreSQL:计算两个时间戳之间的持续时间(小时),并从周末中减去小时数

hgncfbus  于 2023-05-06  发布在  PostgreSQL
关注(0)|答案(1)|浏览(377)

我已经尝试创建以下SQL查询(PostgreSQL 12.14)好几天了,但我无法弄清楚。
查询应该计算两个时间戳之间的持续时间(以小时为单位),但只计算属于工作日的小时数。
示例:
创建日期:2023年4月27日14:00:00 NOW()= 2023年5月2日- 08:00:00
正确的结果应为66小时:27.04 = 10 h(从14:00到00:00)28.04 = 24 h 29.04 = 0 h(星期六)30.04 = 0 h(星期日)01.05 = 24 h 02.05 = 8h(从00:00到08:00)
谢谢你的帮助迈克尔

mkshixfv

mkshixfv1#

如果我理解你想要正确的以下给出它。您正在查找几个时间间隔内的sum小时数。这些间隔被定义为start时间戳和当天结束之间、end的当天开始和当天该时间的实际时间之间、以及startend日期之间每天24小时的间隔;不包括星期六和星期天。(参见demo

with each_day (start_dtm, end_dtm, act_dt) as 
     ( select start_dtm, end_dtm 
            , generate_series( date_trunc('day', start_dtm) 
                             , date_trunc('day', end_dtm )  
                             , interval '1 day'
                             ) act_dt
         from (select start_dtm, end_dtm from hours) h
     ) -- select * from each_day;
   , hours_per_day (start_dtm, end_dtm, act_dt, hrs) as 
     ( select each_day.*
            ,case when date_trunc('day', start_dtm) = act_dt  then act_dt+interval '1 day' - start_dtm
                  when date_trunc('day', end_dtm) = act_dt    then end_dtm - act_dt
                  else                                        make_interval (hours => 24) 
                end
         from each_day
        where extract(isodow from act_dt) < 6 
     )  -- select * from hours_per_day; 
select start_dtm, end_dtm, extract(hours from sum(hrs)) "Duration in Hours"
  from hours_per_day
 group by start_dtm, end_dtm
 order by date_trunc('day', start_dtm), end_dtm;

查询首先创建2个CTE。each_day CTE使用generate series函数扩展开始日期和结束日期,包括它们之间的日期。第二个CTE hours_per_day是真实的的主力。它确定日期是期间的第一天还是最后一天。对于每一天,它计算这些天的适当间隔(减去时间戳得到间隔),并且对于中间天,创建24小时(1天)的间隔。此外,它还取消了星期六和星期日。最后,主查询计算这些时间间隔的sum并提取小时数。

相关问题