Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / Oracle [игнор отключен] [закрыт для гостей] / отлов "опоздунов" на работу / 14 сообщений из 14, страница 1 из 1
03.12.2017, 14:54
    #39563275
abrahs
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
отлов "опоздунов" на работу
Всем привет, имеется задачка в которой необходимо вывести список сотрудников и число опозданий для каждого за месяц. Рабочий день с 9, в течении дня они могут несколько раз выходить, заходить, это фиксируется в журнале, в 00 считается что все точно ушли. Сб, вс выходные и не учитываются.


таблица слудующая:
id sub_id dtime type
Номер записи, id сотрудника, дата и время записи, тип (вход / выход).

На форуме находил попытки реализации подобного под mysql, общее решение так и не было найдено.
Может кто уже сталкивался с реализацией подобного? Каким образом можно не учитывать повторные входы и выходы в течении дня?
...
Рейтинг: 0 / 0
03.12.2017, 15:55
    #39563287
mefman
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
отлов "опоздунов" на работу
сгуппировать по дням. смотреть только min(time) за каждый день.
...
Рейтинг: 0 / 0
03.12.2017, 16:30
    #39563293
отлов "опоздунов" на работу
Как планируется отсекать выходные, кроме сб и вс?
Будет ли опозданием присутствие на работе только с 6:00 по 8:55? Да и вообще, отпуск, прогул, больничный.

abrahsКаким образом можно не учитывать повторные входы и выходы в течении дня?Зачем учитывать выходы, если не учитывается время работы, а только первый вход?
Пример выбора крайней записи
...
Рейтинг: 0 / 0
03.12.2017, 17:27
    #39563310
abrahs
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
отлов "опоздунов" на работу
заядлый опоздун, прочие выходные и т.п. по условию можно не учитывать, только сб и вс.

Будет ли опозданием присутствие на работе только с 6:00 по 8:55? Да
Как я понимаю главное правило это присутствие на рабочем месте в момент наступления 9 часов.
...
Рейтинг: 0 / 0
03.12.2017, 18:12
    #39563322
отлов "опоздунов" на работу
Проверка только на 9:00
Код: plsql
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.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
with
calend as
 (select d, (d + interval '9' hour) utro
    from (select trunc(sysdate) - level d from dual connect by level <= 7)
   where to_char(d, 'D') not in ('6', '7')),
t as
 (select 1 sub_id, to_date('28.11.2017 08:45', 'dd.mm.yyyy hh24:mi') dtime, 'in' tp from dual union all
  select 1 sub_id, to_date('28.11.2017 08:55', 'dd.mm.yyyy hh24:mi') dtime, 'out' tp from dual union all
  select 1 sub_id, to_date('30.11.2017 08:55', 'dd.mm.yyyy hh24:mi') dtime, 'in' tp from dual union all
  select 1 sub_id, to_date('30.11.2017 18:45', 'dd.mm.yyyy hh24:mi') dtime, 'out' tp from dual union all
  select 2 sub_id, to_date('30.11.2017 08:45', 'dd.mm.yyyy hh24:mi') dtime, 'in' tp from dual union all
  select 2 sub_id, to_date('30.11.2017 15:30', 'dd.mm.yyyy hh24:mi') dtime, 'out' tp from dual union all
  select 3 sub_id, to_date('29.11.2017 08:45', 'dd.mm.yyyy hh24:mi') dtime, 'in' tp from dual union all
  select 3 sub_id, to_date('29.11.2017 15:30', 'dd.mm.yyyy hh24:mi') dtime, 'out' tp from dual),
t2 as
 (select sub_id,
         dtime d_in,
         (select t1.dtime
            from t t1
           where t1.sub_id = t.sub_id
             and trunc(t1.dtime) = trunc(t.dtime)
             and t1.dtime > t.dtime
             and t1.tp = 'out') d_out
    from t
   where t.tp = 'in')
select sub_id,
       (select count(*) || ': ' || listagg(to_char(c.d, 'dd/mm'), ', ') within group(order by c.d)
          from calend c
         where not exists
               (select null
                  from t2 t3
                 where c.utro between t3.d_in and t3.d_out
                   and t3.sub_id = t2.sub_id)) "Опоздания/Прогулы"
  from t2
 group by sub_id

abrahsБудет ли опозданием присутствие на работе только с 6:00 по 8:55? Да
Как я понимаю главное правило это присутствие на рабочем месте в момент наступления 9 часов.06:00-08:55 пахал
08:55-09:15 за булочкой сбегал / покурил
09:15-20:30 пахал

Тоже опоздун?
...
Рейтинг: 0 / 0
03.12.2017, 18:28
    #39563324
abrahs
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
отлов "опоздунов" на работу
заядлый опоздун, теоретически надо добавлять в таком случае общее отработанное время за день и отталкиваться от него, но т.к. в условиях этого нет и существует проблема того, что человек допустим зашёл на пару минут до начала рабочего дня и ушёл с концами думаю отслеживать именно присутствие во время открытия.
...
Рейтинг: 0 / 0
03.12.2017, 18:49
    #39563327
abrahs
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
отлов "опоздунов" на работу
заядлый опоздун (select 1 sub_id, to_date('28.11.2017 08:45', 'dd.mm.yyyy hh24:mi') dtime, 'in' tp from dual union all
select 1 sub_id, to_date('28.11.2017 08:55', 'dd.mm.yyyy hh24:mi') dtime, 'out' tp from dual union all
select 1 sub_id, to_date('30.11.2017 08:55', 'dd.mm.yyyy hh24:mi') dtime, 'in' tp from dual union all
select 1 sub_id, to_date('30.11.2017 18:45', 'dd.mm.yyyy hh24:mi') dtime, 'out' tp from dual union all
select 2 sub_id, to_date('30.11.2017 08:45', 'dd.mm.yyyy hh24:mi') dtime, 'in' tp from dual union all
select 2 sub_id, to_date('30.11.2017 15:30', 'dd.mm.yyyy hh24:mi') dtime, 'out' tp from dual union all
select 3 sub_id, to_date('29.11.2017 08:45', 'dd.mm.yyyy hh24:mi') dtime, 'in' tp from dual union all
select 3 sub_id, to_date('29.11.2017 15:30', 'dd.mm.yyyy hh24:mi') dtime, 'out' tp from dual),


получаю ошибку ORA-00972: identifier is too long т.к. идентификатор больше 30 байт, каким образом вы это обходите?
...
Рейтинг: 0 / 0
03.12.2017, 19:27
    #39563339
отлов "опоздунов" на работу
abrahsполучаю ошибку ORA-00972: identifier is too long т.к. идентификатор больше 30 байт, каким образом вы это обходите?select lengthb("Опоздания/Прогулы") from dual;
Попробуй заменить "Опоздания/Прогулы" на "Опоздания" или на cmnt :)
...
Рейтинг: 0 / 0
03.12.2017, 19:34
    #39563343
abrahs
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
отлов "опоздунов" на работу
заядлый опоздун, спасибо большое) затупил, думал где дата прописана по байтам не проходила)
...
Рейтинг: 0 / 0
04.12.2017, 11:54
    #39563574
Stax
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
отлов "опоздунов" на работу
abrahsзаядлый опоздун, теоретически надо добавлять в таком случае общее отработанное время за день и отталкиваться от него, но т.к. в условиях этого нет и существует проблема того, что человек допустим зашёл на пару минут до начала рабочего дня и ушёл с концами думаю отслеживать именно присутствие во время открытия.

ето реальная проблема

софт покупной
1) прошел вертушку 8:30, в 8:55 вышел покурить (в помещении запрещено), зашел в 9:05 - опоздал
2) работа с ночи предыдущего для - тоже считает опоздавшим
3) на вход не отработал датчик с вертушки - опоздал

и тд

.....
stax
...
Рейтинг: 0 / 0
04.12.2017, 12:33
    #39563608
Dshedoo
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
отлов "опоздунов" на работу
Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
with q as (select 1 sub_id, to_date('28.11.2017 08:45', 'dd.mm.yyyy hh24:mi') dtime, 'in' tp from dual union all
 select 1 sub_id, to_date('28.11.2017 08:55', 'dd.mm.yyyy hh24:mi') dtime, 'out' tp from dual union all
 select 1 sub_id, to_date('25.11.2017 08:55', 'dd.mm.yyyy hh24:mi') dtime, 'in' tp from dual union all 
 select 1 sub_id, to_date('30.11.2017 08:55', 'dd.mm.yyyy hh24:mi') dtime, 'in' tp from dual union all
 select 1 sub_id, to_date('30.11.2017 18:45', 'dd.mm.yyyy hh24:mi') dtime, 'out' tp from dual union all
 select 2 sub_id, to_date('30.11.2017 08:45', 'dd.mm.yyyy hh24:mi') dtime, 'in' tp from dual union all
 select 2 sub_id, to_date('30.11.2017 15:30', 'dd.mm.yyyy hh24:mi') dtime, 'out' tp from dual union all
 select 3 sub_id, to_date('29.11.2017 08:45', 'dd.mm.yyyy hh24:mi') dtime, 'in' tp from dual union all
 select 3 sub_id, to_date('29.11.2017 15:30', 'dd.mm.yyyy hh24:mi') dtime, 'out' tp from dual)
 
 select q1.sub_id, min(q1.dtime) as "in", nvl(max(q2.dtime),trunc(q1.dtime)+1-1/86400) as "out" 
from q q1 left join q q2 on q1.sub_id = q2.sub_id and q1.tp = 'in' and q2.tp = 'out' and trunc(q1.dtime) = trunc(q2.dtime)
group by q1.sub_id, trunc(q1.dtime)
...
Рейтинг: 0 / 0
04.12.2017, 12:57
    #39563628
отлов "опоздунов" на работу
заядлый опоздун
Код: plsql
1.
2.
3.
4.
5.
6.
select t1.dtime
  from t t1
 where t1.sub_id = t.sub_id
   and trunc(t1.dtime) = trunc(t.dtime)
   and t1.dtime > t.dtime
   and t1.tp = 'out'

Опечатка, конечно же "select min(t1.dtime)"

Dshedoo,
Учет только последнего выхода покажет переработку при работе с "сиестой" (огромным обедом).
...
Рейтинг: 0 / 0
04.12.2017, 13:01
    #39563632
отлов "опоздунов" на работу
Dshedoo,

И не проверить присутствие сотрудника в конкретный момент времени (как в условии - 9:00)
...
Рейтинг: 0 / 0
04.12.2017, 14:52
    #39563755
Dshedoo
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
отлов "опоздунов" на работу
Код: plsql
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.
26.
27.
28.
with q as (select 1 sub_id, to_date('28.11.2017 09:45', 'dd.mm.yyyy hh24:mi') dtime, 'in' tp from dual union all
 select 1 sub_id, to_date('28.11.2017 09:55', 'dd.mm.yyyy hh24:mi') dtime, 'out' tp from dual union all
 select 1 sub_id, to_date('25.11.2017 08:55', 'dd.mm.yyyy hh24:mi') dtime, 'in' tp from dual union all 
 select 1 sub_id, to_date('30.11.2017 08:55', 'dd.mm.yyyy hh24:mi') dtime, 'in' tp from dual union all
 select 1 sub_id, to_date('30.11.2017 18:45', 'dd.mm.yyyy hh24:mi') dtime, 'out' tp from dual union all
 select 2 sub_id, to_date('30.11.2017 08:45', 'dd.mm.yyyy hh24:mi') dtime, 'in' tp from dual union all
 select 2 sub_id, to_date('30.11.2017 08:55', 'dd.mm.yyyy hh24:mi') dtime, 'out' tp from dual union all
 select 2 sub_id, to_date('30.11.2017 15:30', 'dd.mm.yyyy hh24:mi') dtime, 'in' tp from dual union all
 select 2 sub_id, to_date('30.11.2017 18:30', 'dd.mm.yyyy hh24:mi') dtime, 'out' tp from dual union all 
 select 3 sub_id, to_date('29.11.2017 08:45', 'dd.mm.yyyy hh24:mi') dtime, 'in' tp from dual union all
 select 3 sub_id, to_date('29.11.2017 15:30', 'dd.mm.yyyy hh24:mi') dtime, 'out' tp from dual)
 
, w as (select q1.sub_id
, min(q1.dtime) as "in"
, nvl(min(q2.dtime),trunc(q1.dtime)+1-1/86400) as "out"
,to_date(trunc(min(q1.dtime))||' 09:00:00','DD.MM.YYYY HH24:mi:ss')
, sum((nvl(min(q2.dtime),trunc(q1.dtime)+1-1/86400)- min(q1.dtime))*24*60) over(partition by q1.sub_id, trunc(q1.dtime)) as rab
from q q1 left join q q2 on q1.sub_id = q2.sub_id and q1.tp = 'in' and q2.tp = 'out' and trunc(q1.dtime) = trunc(q2.dtime)
and q1.dtime <= q2.dtime
where q1.tp = 'in'
group by q1.sub_id, q1.dtime)

select sub_id
, listagg(to_char("in",'DD.MM.YYYY HH24:MI:SS')||' - '||to_char("out",'DD.MM.YYYY HH24:MI:SS'),', ') WITHIN GROUP(order by sub_id, "in")
, lpad(trunc(rab/60),2,0)||':'||lpad(trunc(mod(rab,60)),2,0)||':'||lpad((mod(rab,60)-trunc(mod(rab,60)))*60,2,0) as "rabotal(HH:MI:SS)"
, case when min("in") < to_date(to_char(min("in"),'DD.MM.YYYY')||' 09:00:00','DD.MM.YYYY HH24:MI:SS') then 'N' else 'Y' end as opozdyn
from w
group by sub_id, trunc("in"), rab



Так сойдёт?
...
Рейтинг: 0 / 0
Форумы / Oracle [игнор отключен] [закрыт для гостей] / отлов "опоздунов" на работу / 14 сообщений из 14, страница 1 из 1
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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