Presto: разница во времени между двумя метками времени в минутах только для рабочего времени - PullRequest
0 голосов
/ 15 октября 2019

Я пытаюсь найти разницу во времени в минутах между двумя датами, но я хочу, чтобы разница учитывала время открытия магазина. Магазин работает только 9 часов в день и только в будние дни (выходные также закрыты), поэтому разница во времени должна учитывать время согласно рабочим часам.

Пример: 18.07.2009 9:50 - 22.07.2009 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

1 Ответ

1 голос
/ 16 октября 2019

Ну, я не знаю, какой запрос вы пытались сделать, но я делаю то, чем он не является - и это Постгрес. Postgres не имеет функций date_diff и date_parse и не поддерживает спецификаторы формата% m /% d / ... (SQL Server?)Глядя на оператор Excel, он содержит макрос, который ваш оператор не пытается приспособить: NETWORKDAYS. Этот макрос возвращает количество сб, вс и выходных за указанный период данных. В Postgres все это можно преобразовать в один оператор SQL (ну почти). Далее я обернул этот оператор в функцию SQL, которая возвращает желаемое значение, однако контрольного примера 1 никогда не бывает достаточно. Также я включил функцию SQL для возврата логического значения, если день является выходным днем ​​(в противном случае он равен false). Но не зная вашего отпуска в настоящее время он всегда возвращает ложь.

-- 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);
...