【问题标题】:Presto: Time difference in minutes between two timestamps only for working hoursPresto:两个时间戳之间的时间差(以分钟为单位)仅适用于工作时间
【发布时间】:2020-02-11 13:12:40
【问题描述】:

我试图找出两个日期之间的时间差(以分钟为单位),但我希望该差值能够说明商店营业的时间。店铺每天只营业 9 小时,而且只在工作日营业(周末也关门),因此时差应按营业时间计算。

示例:2019 年 7 月 18 日上午 9:50 - 2019 年 7 月 22 日上午 10:02

SELECT date_diff('minute', date_parse('7/18/2019 9:50:00 AM','%m/%d/%Y %h:%i:%s %p'), date_parse('7/22/2019 10:02:00 AM','%m/%d/%Y %h:%i:%s %p'))

这给出的答案是 5772。但我希望答案是 1092。

excel公式为

A1 = 7/18/2019 9:50 AM
B1 = 7/22/2019 10:02 AM
if(OR(A1="",A1="NULL",B1="",B1="NULL"),"",(A1-B1)*24*60 - (days(A1,B1)+1-NETWORKDAYS(A1,B1))*24*60 - (NETWORKDAYS(A1,B1)-1)*15*60)

这个版本适合我,但有更好的方法吗?另外,如果我们可以在 presto 上编写一个函数,我不知道如何在 presto 上编写一个可调用函数。

with working_days AS
(
select count(*) as wd from unnest(sequence (cast('2017-06-07' as date), cast('2017-06-13' as date))) t(x)
WHERE extract (day_of_week from x) < 6 
)
select date_diff('minute', cast('2017-06-07 11:19:11.287' as timestamp), cast('2017-06-13 09:53:14.750' as timestamp)) - 
       ((date_diff('day', cast('2017-06-07' as date), cast('2017-06-13' as date))+1 - wd)*24*60 + (wd - 1)*16*60)
FROM working_days

【问题讨论】:

  • 这可能是您的解决方案:stackoverflow.com/questions/1839319/…
  • 无法使其工作。从 unnest 中选择 x(sequence(cast(date_parse('7/22/2019 10:02:00 AM','%m/%d/%Y %h:%i:%s %p') 作为日期), cast(date_parse('7/22/2019 10:02:00 AM','%m/%d/%Y %h:%i:%s %p') as date))) t(x) 这是也不为我工作!试图看看什么可以工作

标签: postgresql datediff presto date-difference


【解决方案1】:

好吧,我不知道您尝试的查询是什么,但我做的不是它——那就是 Postgres。 Postgres 没有 date_diff 和 date_parse 函数,也不支持格式说明符 %m/%d/...(SQL Server?)
查看 Excel 语句,它包含您的语句不尝试容纳的宏:NETWORKDAYS。此宏返回指定数据周期内的周六、周日和节假日的数量。在 Postgres 中,整个事情都可以转换成一条 SQL 语句(差不多)。在下文中,我将该语句包装在一个返回所需值的 SQL 函数中,但是测试用例 1 永远不够。此外,如果一天是假期,我还包含一个 SQL 函数以返回布尔值(否则为假)。但目前不知道您的假期,它总是返回错误。

-- Holiday Routine
create or replace function Is_Holiday(date_in timestamp)
returns boolean
language sql  
as $$
    -- TODO: determine if parameter is a holiday. if so return true
    select false;
$$;

--- Main Routine
create or replace function Work_Minuets_in_Period(date1_in timestamp, date2_in timestamp) 
returns integer
language sql strict
as $$
     with proper_dates as
         ( select least (date1_in,date2_in) start_date, greatest(date1_in, date2_in) end_date)
       , date_interval as (select end_date - start_date intv from proper_dates)
       , non_work_days as
         (select count(*)::double precision non_work                  -- for operation with extract( ... ) function 
            from (select generate_series            
                         ( start_date
                         , end_date
                         , interval '1 day'
                         ) this_day
                   from proper_dates  ) ds
           where extract(isodow from this_day ) in (6,7)             -- sat, sun
              or is_holiday(this_day)                                -- holiday?
         )
     select (9*60*(extract(days from intv) - non_work)               -- full work days (9 hr each)
            +  60*extract(hours from intv)                           -- partial hours from interval
            +  extract(minutes from intv) )::integer                 -- minuets
       from date_interval, non_work_days; 
$$;             

--- test (calling function)
select * from Work_Minuets_in_Period('7/22/2019 10:02 AM'::timestamp ,'7/18/2019 9:50 AM'::timestamp);

【讨论】:

  • 我在 Presto 上这样做
猜你喜欢
  • 2021-01-04
  • 2020-06-08
  • 1970-01-01
  • 1970-01-01
  • 2021-05-14
  • 1970-01-01
  • 2021-05-12
  • 1970-01-01
  • 2020-01-02
相关资源
最近更新 更多