powered by simpleCommunicator - 2.0.53     © 2025 Programmizd 02
Форумы / PostgreSQL [игнор отключен] [закрыт для гостей] / Выбор парных записей
7 сообщений из 7, страница 1 из 1
Выбор парных записей
    #39556094
good32
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Доброго времени суток. Нужна помощь в выборке записей, есть таблица историй в ней записываются действия прихода и ухода. Необходимо выбрать все приходы за последние 24 часа, а так же парные для них уходы. Пример данных, есть приход в '2017-01-01 12:00:00' и парный для него уход в '2017-01-01 22:00:00', но в этот промежуток (24 часа) добавляется приход в '2017-01-02 05:00:00' и парный уход в '2017-01-02 13:00:00'.
...
Рейтинг: 0 / 0
Выбор парных записей
    #39556099
Фотография Щукина Анна
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
good32,

приходы-уходы всегда парные? вариант, что человек пришел, но вышел в окно - точно не встречаются?
...
Рейтинг: 0 / 0
Выбор парных записей
    #39556109
good32
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Щукина Анна,

Не важно сколько приходов сделано, берем по факту последний приход и парный для него уход.
...
Рейтинг: 0 / 0
Выбор парных записей
    #39556126
Фотография Щукина Анна
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
good32,

тогда lead/lag в сортировке по дате события (приход/уход). если речь идет об учете рабочего времени, то еще partition by <по сотруднику>
...
Рейтинг: 0 / 0
Выбор парных записей
    #39556137
good32
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Щукина Анна,

Можно более подробнее, с примером? К сожалению, не так хорошо понимаю принцип работы оконных функций.
В таблице историй, есть колонка id пользователя, status означающий событие и дата этого события.
...
Рейтинг: 0 / 0
Выбор парных записей
    #39556509
Фотография Щукина Анна
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
good32,

всё же момент с допустимостью нескольких подряд событий одного типа не раскрыт. поэтому буду исходить из предположения, что может быть несколько входов подряд, несколько выходов. могут быть "висячие" входы без парных им выходов и наоборот.
примерное направление движение будет выглядеть так:
Код: 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.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
/* Демонстрационный набор тестовых данных , тут I,i - вход, O,o - выход*/ 
with t as 
  (
    select 1 as user_id, to_date('2017-11-01','yyyy-mm-dd') as x_dt, 'I' as event_type union all
    select 1 as user_id, to_date('2017-11-02','yyyy-mm-dd') as x_dt, 'I' as event_type union all
    select 1 as user_id, to_date('2017-11-03','yyyy-mm-dd') as x_dt, 'O' as event_type union all
    select 1 as user_id, to_date('2017-11-04','yyyy-mm-dd') as x_dt, 'O' as event_type union all
    select 2 as user_id, to_date('2017-11-05','yyyy-mm-dd') as x_dt, 'I' as event_type union all
    select 2 as user_id, to_date('2017-11-06','yyyy-mm-dd') as x_dt, 'O' as event_type union all
    select 2 as user_id, to_date('2017-11-07','yyyy-mm-dd') as x_dt, 'I' as event_type union all
    select 2 as user_id, to_date('2017-11-08','yyyy-mm-dd') as x_dt, 'O' as event_type union all
    select 3 as user_id, to_date('2017-11-09','yyyy-mm-dd') as x_dt, 'O' as event_type union all
    select 3 as user_id, to_date('2017-11-10','yyyy-mm-dd') as x_dt, 'I' as event_type union all
    select 3 as user_id, to_date('2017-11-11','yyyy-mm-dd') as x_dt, 'I' as event_type union all
    select 3 as user_id, to_date('2017-11-12','yyyy-mm-dd') as x_dt, 'O' as event_type union all
    select 4 as user_id, to_date('2017-11-13','yyyy-mm-dd') as x_dt, 'I' as event_type union all
    select 5 as user_id, to_date('2017-11-14','yyyy-mm-dd') as x_dt, 'O' as event_type
  )
/* Возможный вариант решения поставленной задачи*/
select user_id, d1 as date_i, d2 as date_o
from 
  (--  свертка подряд идущих однотипных событий в одно, для входов - поиск ближайшего выхода
    select user_id, event_type, max(x_dt) as d1
         , case when event_type = 'I' and lead(event_type) over(partition by user_id order by min(x_dt)) = 'O'
           then lead(min(x_dt)) over(partition by user_id order by min(x_dt)) end as d2
    from 
      (
        select user_id, x_dt, event_type
             , row_number() over(partition by user_id, event_type order by x_dt) -
               row_number() over(partition by user_id order by x_dt) as x_group
        from   t
      ) dv0
    group by user_id, event_type, x_group
  ) dv1
where event_type = 'I'
order by user_id, date_i

Проверка

Более точное решение, надуюсь, сможете доработать самостоятельно. :)
...
Рейтинг: 0 / 0
Выбор парных записей
    #39556576
good32
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Щукина Анна,

Спасибо, но я так и не смог доработать самостоятельно т.к в условии необходимо выбрать все приходы за последние 24 часа, после чего нужно выбрать все парные для него уходы. В случае если есть ошибочная записи прихода, т.е 2 прихода и 1 уход, нужно брать за основу вторую запись. С уходом все иначе, берется первая запись.
...
Рейтинг: 0 / 0
7 сообщений из 7, страница 1 из 1
Форумы / PostgreSQL [игнор отключен] [закрыт для гостей] / Выбор парных записей
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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