powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Firebird, InterBase [игнор отключен] [закрыт для гостей] / Как вычислить длительность работы по временным отметкам
25 сообщений из 31, страница 1 из 2
Как вычислить длительность работы по временным отметкам
    #38576783
miwaonline
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Возникла задача подсчитать (примерно, с точностью до десятков минут) сколько времени проводят сотрудники на рабочем месте. Все исходные данные, которые можно накопать, выглядят примерно так.

Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
CREATE TABLE TEST1 (
    OPERATOR_ID INTEGER,
    PROCESS_TIME TIME);


INSERT INTO TEST1 (OPERATOR_ID, PROCESS_TIME) VALUES (1, '9:00:00');
INSERT INTO TEST1 (OPERATOR_ID, PROCESS_TIME) VALUES (1, '9:02:35');
INSERT INTO TEST1 (OPERATOR_ID, PROCESS_TIME) VALUES (1, '9:12:11');
INSERT INTO TEST1 (OPERATOR_ID, PROCESS_TIME) VALUES (1, '9:26:00');
INSERT INTO TEST1 (OPERATOR_ID, PROCESS_TIME) VALUES (2, '9:31:18');
INSERT INTO TEST1 (OPERATOR_ID, PROCESS_TIME) VALUES (2, '9:35:54');
INSERT INTO TEST1 (OPERATOR_ID, PROCESS_TIME) VALUES (2, '9:41:21');
INSERT INTO TEST1 (OPERATOR_ID, PROCESS_TIME) VALUES (2, '9:48:18');
INSERT INTO TEST1 (OPERATOR_ID, PROCESS_TIME) VALUES (2, '9:55:55');
INSERT INTO TEST1 (OPERATOR_ID, PROCESS_TIME) VALUES (1, '10:01:01');
INSERT INTO TEST1 (OPERATOR_ID, PROCESS_TIME) VALUES (1, '10:03:15');
INSERT INTO TEST1 (OPERATOR_ID, PROCESS_TIME) VALUES (3, '10:10:11');
INSERT INTO TEST1 (OPERATOR_ID, PROCESS_TIME) VALUES (3, '10:12:12');
INSERT INTO TEST1 (OPERATOR_ID, PROCESS_TIME) VALUES (3, '10:16:16');



Тоесть есть только идентификаторы операторов и моменты времени, когда они были на рабочем месте. По данных с примера считаем, что оператор1 был на рабочем месте с 9:00:00 по 9:26:00 и потом с 10:01:01 по 10:03:15, оператор2 - с 9:31:18 по 9:55:55 и т.д.

В оконцовке нужен примерно такой результат:

Оператор1 - 28 минут (допускается с 27 по 30 в засомости от округления секунд).
Оператор2 - 34-36 минут.
Оператор3 - 5-7 минут.

Конечная конструкция будет в execute block-е, так что одним запросом и оконными функциями тройки обходиться не обязательно :)

Сам я выкрутился следующим образом

Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
  for select min(process_time), operator_id
    from test1
    group by 2
    into ctime, coperator do
  begin
    RDB$SET_CONTEXT('USER_TRANSACTION', 'worktimelen' || :coperator, 0);
    RDB$SET_CONTEXT('USER_TRANSACTION', 'worktimepre' || :coperator, :ctime);
  end
  prevoperator = -1;

  for select process_time, operator_id
    from test1
    order by process_time
    into ctime, coperator
  do begin
    if (:coperator = :prevoperator) then begin
      RDB$SET_CONTEXT('USER_TRANSACTION', 'worktimelen' || :coperator,
                      cast(RDB$GET_CONTEXT('USER_TRANSACTION', 'worktimelen' || :coperator) as float) +
                      :ctime - cast(RDB$GET_CONTEXT('USER_TRANSACTION', 'worktimepre' || :coperator) as time));
      RDB$SET_CONTEXT('USER_TRANSACTION', 'worktimepre' || :coperator, :ctime);
    end else begin
      RDB$SET_CONTEXT('USER_TRANSACTION', 'worktimepre' || :coperator, :ctime);
      prevoperator = :coperator;
    end
  end



Интересует, есть ли менее дуболомные варианты решения такой задачи при заданных исходных условиях (тоесть столбца "длительность" нету и пройтись простым суммированием по нему, соответственно, не получится).
...
Рейтинг: 0 / 0
Как вычислить длительность работы по временным отметкам
    #38576799
Фотография DarkMaster
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
miwaonline,

А в секундах достаточно будет?

Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
  start_time=9*3600;  -- 9:00:00 как начало смены для оператора

   select sum(extract (hour from process_time)*3600)+
                  extract(minute from process_time)*60+
                  extract(second from process_time)-:start_time) 
   from test1
   where operator_id=:op_id
   into :op_time_in_sec;
...
Рейтинг: 0 / 0
Как вычислить длительность работы по временным отметкам
    #38576801
Фотография DarkMaster
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
DarkMaster,

.... а id самих операторов - через DISTINCT
...
Рейтинг: 0 / 0
Как вычислить длительность работы по временным отметкам
    #38576804
pizmon
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
а Оператор1 - 28 минут, потому что был Оператор2, а если бы его не было, то было бы 63 минуты?
...
Рейтинг: 0 / 0
Как вычислить длительность работы по временным отметкам
    #38576807
miwaonline
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
pizmonа Оператор1 - 28 минут, потому что был Оператор2, а если бы его не было, то было бы 63 минуты?
Да.

Тоесть, операторы могут работать повторно в течении суток и период их отсутствия не должен быть защитан как рабочее время.
...
Рейтинг: 0 / 0
Как вычислить длительность работы по временным отметкам
    #38576810
Ivan_Pisarevsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
INSERT INTO TEST1 (OPERATOR_ID, PROCESS_TIME) VALUES (1, '9:26:00');
INSERT INTO TEST1 (OPERATOR_ID, PROCESS_TIME) VALUES (2, '9:31:18');

Оператор1 ретировался ровно в 9.26, а второй явился строго в 9.31? Как-то не совсем честно, по отношению к операторам. Поделить интервал и раздать в некой пропорции?
...
Рейтинг: 0 / 0
Как вычислить длительность работы по временным отметкам
    #38576811
Фотография DarkMaster
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
miwaonline,

А, блин, недочитал - извини... Тут еще надо периоды работал/неработал.
...
Рейтинг: 0 / 0
Как вычислить длительность работы по временным отметкам
    #38576816
Ivan_Pisarevsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Я бы лично предпочел gtt вместо контекстных переменных, гарантированно хватит места под любое кол-во операторов, хотя судя по вводным и переменных хватает с запасом, но тем не менее.
...
Рейтинг: 0 / 0
Как вычислить длительность работы по временным отметкам
    #38576817
m7m
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
miwaonlineИнтересует, есть ли менее дуболомные варианты решения такой задачи при заданных исходных условиях (тоесть столбца "длительность" нету и пройтись простым суммированием по нему, соответственно, не получится).
Написать процедуру которая будет возвращать "длительность", и уже потом суммировать
...
Рейтинг: 0 / 0
Как вычислить длительность работы по временным отметкам
    #38576830
miwaonline
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Ivan_PisarevskyINSERT INTO TEST1 (OPERATOR_ID, PROCESS_TIME) VALUES (1, '9:26:00');
INSERT INTO TEST1 (OPERATOR_ID, PROCESS_TIME) VALUES (2, '9:31:18');

Оператор1 ретировался ровно в 9.26, а второй явился строго в 9.31? Как-то не совсем честно, по отношению к операторам. Поделить интервал и раздать в некой пропорции?

Если делать по-честному, тогда - да. Но сейчас я даже "нечестно" не очень хорошо это делаю.

Насчет gtt - согласен; нефиг мне контекстными переменными разбрасываться :)

m7m,

А откуда процедура возьмет длительности, если их нету; есть только моменты времени когда сканировалась карточка оператора, и все.
...
Рейтинг: 0 / 0
Как вычислить длительность работы по временным отметкам
    #38576834
Ivan_Pisarevsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
miwaonlineА откуда процедура возьмет длительности, если их нетуприджойнить саму на себя по критерию дата больше текущей, правда это больше напоминает sql-ex а не работающее решение.
...
Рейтинг: 0 / 0
Как вычислить длительность работы по временным отметкам
    #38576837
miwaonline
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Ivan_PisarevskymiwaonlineА откуда процедура возьмет длительности, если их нетуприджойнить саму на себя по критерию дата больше текущей, правда это больше напоминает sql-ex а не работающее решение.

И опять же промежутки между двумя операторами потеряются, если я тебя правильно понял.
...
Рейтинг: 0 / 0
Как вычислить длительность работы по временным отметкам
    #38576839
Ivan_Pisarevsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
miwaonlineне очень хорошо это делаю.алгоритмически код довольно тривиальный, идешь по своему запросу(ты его уже привел), пока не сменится оператор, как сменился, то "update or insert into gtt" если его еще нет в гтт, то пишем, если есть, если есть, то увеличиваем его счетчик. потом простой селект из гтт.
...
Рейтинг: 0 / 0
Как вычислить длительность работы по временным отметкам
    #38576842
Ivan_Pisarevsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
miwaonlineпромежутки между двумя операторами потеряютсясмотря как джойнить. хотя мне кажется алгоритмический код здесь будет быстрее и более понятным.
...
Рейтинг: 0 / 0
Как вычислить длительность работы по временным отметкам
    #38576851
Dimitry Sibiryakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
miwaonlineСам я выкрутился следующим образом
А что если так:
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
aaa = 1;
worktimelen = 0;
prevoperator = -1;
for select operator_id, process_time from test1 order by 1,2 into :coperator,:ctime do
  begin
   if (coperator <> prevoperator) then
    begin
     suspend;
     prevoperator = coperator;
     sss = 0;
    end;
   worktimelen = worktimelen + (current_time - ctime) * aaa;
   aaa = -aaa;
  end;
  suspend;


Будет нормально отработана ситуация когда оператор ещё сидит на месте.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
Как вычислить длительность работы по временным отметкам
    #38576852
m7m
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
miwaonlinem7m,

А откуда процедура возьмет длительности, если их нету; есть только моменты времени когда сканировалась карточка оператора, и все.

а в чем проблема-то???
читаем последовательно отсортированный по PROCESS_TIME набор данных
и считаем длительность, не забывая обрабатывать смену OPERATOR_ID
и конец набора данных
...
Рейтинг: 0 / 0
Как вычислить длительность работы по временным отметкам
    #38576874
Таблоид
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
"скучно без водки" (С) (в смысле, без оконных функций :)).
Можно так попробовать:
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
recreate table optime (
    op_id integer,
    op_dts time);
create index optime_dts on optime(op_dts);
commit;

insert into optime (op_id, op_dts) values (1, '9:00:00');
insert into optime (op_id, op_dts) values (1, '9:02:35');
insert into optime (op_id, op_dts) values (1, '9:12:11');
insert into optime (op_id, op_dts) values (1, '9:26:00');
insert into optime (op_id, op_dts) values (2, '9:31:18');
insert into optime (op_id, op_dts) values (2, '9:35:54');
insert into optime (op_id, op_dts) values (2, '9:41:21');
insert into optime (op_id, op_dts) values (2, '9:48:18');
insert into optime (op_id, op_dts) values (2, '9:55:55');
insert into optime (op_id, op_dts) values (1, '10:01:01');
insert into optime (op_id, op_dts) values (1, '10:03:15');
insert into optime (op_id, op_dts) values (3, '10:10:11');
insert into optime (op_id, op_dts) values (3, '10:12:12');
insert into optime (op_id, op_dts) values (3, '10:16:16');
commit;

Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
select op_id, sum(sumset) sum_seconds
from(
  select rowset,op_id --,min(op_dts) dts_min, max(op_dts) dts_max
        ,datediff(second from min(op_dts) to max(op_dts)) sumset
  from(
    select (select first 1 b.op_dts 
                from optime b 
              where b.op_id<>a.op_id and b.op_dts>a.op_dts 
              order by op_dts) rowset -- это номер "серии" из записей с одним и тем же op_id
            , a.*
    from optime a
  ) t
  group  by 1,2
)
group by 1


NB: из-за отсутствия ДАТЫ в поле времени будут проблемы при переходе через полночь.
...
Рейтинг: 0 / 0
Как вычислить длительность работы по временным отметкам
    #38577242
miwaonline
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Прошу прощения, отвлекли.

Dimitry Sibiryakov,

В твоем примере из-за order by 1, 2 будут некорректные значения в случае, когда оператор работал несколько раз с перерывами.

m7mmiwaonlinem7m,
А откуда процедура возьмет длительности, если их нету; есть только моменты времени когда сканировалась карточка оператора, и все.
а в чем проблема-то???
читаем последовательно отсортированный по PROCESS_TIME набор данных
и считаем длительность, не забывая обрабатывать смену OPERATOR_ID
и конец набора данных
Я имел в виду, что изначально нету данных по длительности, есть только некоротые контрольные точки, которые гарантировано указывают наличие карты перед сканером, но сколько времени перед считыванием и после него оператор провел на рабочем месте - неизвестно. С учетом вышесказанного с остальным - согласен.

Таблоид,

Ну вот как ты это делаешь? Мало того, что нифига не понятно, оно еще как-то работает. Я теперь пол-вечера буду пытаться понять - как именно %)

Дата, само собой, в реальных данных есть, но переходы через полночь не нужны - работа заканчивается не позже 20 часов.

В целом - спасибо всем откликнувшимся.
...
Рейтинг: 0 / 0
Как вычислить длительность работы по временным отметкам
    #38577243
Dimitry Sibiryakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
miwaonlineВ твоем примере из-за order by 1, 2 будут некорректные значения в случае,
когда оператор работал несколько раз с перерывами.
Не будут. Все периоды работы сложатся, перерывы из них вычтутся. Проверь.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
Как вычислить длительность работы по временным отметкам
    #38577245
miwaonline
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dimitry Sibiryakov,

Само собой, я сейчас проверю и твой пример и Таблоида, только сначала пойму, как они работают :)
...
Рейтинг: 0 / 0
Как вычислить длительность работы по временным отметкам
    #38577246
miwaonline
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dimitry SibiryakovmiwaonlineВ твоем примере из-за order by 1, 2 будут некорректные значения в случае,
когда оператор работал несколько раз с перерывами.
Не будут. Все периоды работы сложатся, перерывы из них вычтутся. Проверь.

А-а-а-а, aaa = -aaa;
Понятно
...
Рейтинг: 0 / 0
Как вычислить длительность работы по временным отметкам
    #38577253
Dimitry Sibiryakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
miwaonlineПонятно
Пардон, моё решение таки неправильное. Я неверно понял задачу: думал, что датчик стоит на
входе и в таблице приведены времена приходов и уходов.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
Как вычислить длительность работы по временным отметкам
    #38577258
Dimitry Sibiryakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
miwaonlineЕсли делать по-честному, тогда - да.
Я сейчас скажу бред, но чем-то мне эта табличка напоминает метод Монте-Карло. Если записей
за день в ней достаточное количество, то периоды работы получаются как общий промежуток,
поделённый на всех в пропорциях их count-ов.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
Как вычислить длительность работы по временным отметкам
    #38577326
Таблоид
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Таблоид"скучно без водки" (С) (в смысле, без оконных функций :))да, невмоготу что-то стало... Миша, открывай трёшку, ей-богу!.. :-))
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
select distinct
     b.op_id
    ,sum(datediff(second from min(b.op_dts) to max(b.op_dts)))over(partition by b.op_id) sum_seconds
from(
    select a.*
    ,dense_rank()over(order by a.op_dts)-dense_rank()over(partition by a.op_id order by a.op_dts) rset
    from optime a
) b
group by rset,b.op_id

Result:OP_IDSUM_SECONDS11694214773365
...
Рейтинг: 0 / 0
Как вычислить длительность работы по временным отметкам
    #38577472
miwaonline
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ТаблоидТаблоид"скучно без водки" (С) (в смысле, без оконных функций :))да, невмоготу что-то стало... Миша, открывай трёшку, ей-богу!.. :-))

Да открыл, открыл. Ну, как минимум поставил снапшот :) Еще когда вы с Денисом пару недель назад говорили, что тестировать ее надо всем сообществом.

Что-то конкретное по оконным функциям можешь посоветовать?
...
Рейтинг: 0 / 0
25 сообщений из 31, страница 1 из 2
Форумы / Firebird, InterBase [игнор отключен] [закрыт для гостей] / Как вычислить длительность работы по временным отметкам
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]