Pull to refresh
32
0
Евгений Бредня @bzq

IT

Send message
Что ж не добавили в рабочие дни ещё 2018-06-09 и 2018-12-29? Не так уж это и утомительно.

У меня сошлись результаты запроса на небольшой тестовой выборке, но не сошлись на большой по реальным данным. Сходу ошибку не вижу, посмотрю ещё попозже.
Круто. Но потерялись периоды, совсем не попадающие на рабочее время.
Потерялись периоды с пустым рабочим временем, нет учёта дополнительных рабочих дней. И что-то как-то распухла магия-то. (:
Почему-то ни разу не видел, чтобы в SLA указывали, что предпраздничные рабочие дни на час короче. В SLA обычно пишут «бла-бла-бла за N часов в рабочее время» и рабочее время определено «с/по в рабочие дни кроме выходных и официальных праздников», всё.

Буду рад, если хоть одно из решений позволит учесть укороченные предпраздничные дни. Когда я эту задачу решал в реальной жизни, я на это заложился, но не пригодилось.
Я отчасти с Вами согласен, но тем не менее в условии я просил учесть праздники за два года и мне сперва пришлось «при необходимости решение можно будет легко дополнить», чтобы погонять на тестовых данных. Я бы не стал проявлять излишний формализм, если бы это был единственный нюанс Вашего решения. Но у Вас не учитываются дополнительные рабочие дни, например, 2018-04-28 был рабочим днём. Также потерялись в выводе периоды, которые совсем не попали на рабочее время.
А вот компактность Вашего решения мне очень нравится.
Интересный подход, пока из опубликованных решений никто не пробовал так считать, но есть ошибка в реализации. Запустите на интервале ('2019-01-01 21:00:00', '2019-01-01 21:00:00'), эффект неожиданный.
Да, в условии интервалы могут быть из 2018-2019 гг., а Вы учли только новогодние праздники 2019 года.
Решение не учитывает праздничные дни.

Про задачку с интервалами сформулируйте более формально, чтобы было понятно какими входными данными оперировать и в какой форме результат получить. С удовольствием порешаю на досуге.
Вроде работает, но без минут нехорошо.
Да, алгоритм-то несложен — посчитать количество рабочих дней, правильно учесть первый и последний дни, всё сложить. Осталось это выразить на SQL.
PS умножить надо на 9
Бинго! Этот вариант запроса уже дал на моих тестовых данных правильный результат.
Не вижу существенной разницы в результатах от предыдущей попытки. Не в том направлении усложняете.
Я боюсь своими комментариями дать Вам слишком много подсказок, поэтому приходится быть не слишком многословным. На моей тестовой выборке расхождения есть.
Согласен, интервалы здесь очень в тему.
Респект, работает! Для «неродной» системы вообще супер. Хотя generate_series можно использовать более прямо, сразу даты генерировать.
Хорошая боевая магия, но пока колдунства недостаточно. Попробуйте IDDQD.
Идея с разбивкой по часам понравилась, получилось очень компактно, но потерялись минуты и секунды.
Да, так лучше.
Решение от DanStopka, прислано мне в личку:
спойлер
Добрый день! Для решения задачи зарегистрировался на хабре, комменты оставлять не дает.
Мое решение:
with periods(id, start_time, stop_time) as (
values(1, '2019-03-29 07:00:00'::timestamp, '2019-04-08 14:00:00'::timestamp),
(2, '2019-04-10 07:00:00'::timestamp, '2019-04-10 20:00:00'::timestamp),
(3, '2019-04-11 12:00:00'::timestamp, '2019-04-12 16:00:00'::timestamp),
(4, '2018-12-28 12:00:00'::timestamp, '2019-01-16 16:00:00'::timestamp)
),

hollydays(dt) as (values ('2019-03-29'))

select p.id, start_time, stop_time, cnt work_hrs from periods
join (
select
id, count(1) cnt
from (select id, generate_series(start_time, stop_time — interval '1 hour', '1 hour') tm from periods) p
where
to_char(tm, 'hh24')::int between 10 and 19 — 1 and
extract(dow from tm) between 1 and 5 and
tm::date not in (select dt::date from hollydays)
group by id
) p on p.id = periods.id

Что-то я смотрю, что рабочие часы воспринимаются почему-то исключительно без рабочих минут. Минуты не забывайте! Я поправил исходные интервалы и ожидаемый ответ, чтобы подчеркнуть наличие минут.

Information

Rating
6,051-st
Location
Москва, Москва и Московская обл., Россия
Works in
Date of birth
Registered
Activity