powered by simpleCommunicator - 2.0.60     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / PostgreSQL [игнор отключен] [закрыт для гостей] / Помогите составить запрос
7 сообщений из 7, страница 1 из 1
Помогите составить запрос
    #35358009
сплю
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Есть таблица
Код: plaintext
1.
2.
3.
4.
5.
action
  id_action int
  id int - ид. клиента
  date timestamp - дата блокировки/разблокировки
  action boolean - 't' - разблокировка, 'f' - блокировка
Это упрощенная таблица блокировок. Нужно получить для заданного месяца кол-во дней, в течении которых клиент был заблокирован.
Заранее спасибо.
...
Рейтинг: 0 / 0
Помогите составить запрос
    #35358234
Как данные представлены в таблице? Всегда ли количество блокировок совпадает с количеством разблокировок? Бывает ли ситуация, когда весь месяц человек был заблокирован? А разблокирован?
...
Рейтинг: 0 / 0
Помогите составить запрос
    #35358244
??????????????
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Еще вопрос - возможно ли ситуация, когда в таблице идут две подряд (в хронологическом порядке) записи с одинаковым типом ACTION (две или более подряд блокировки, две или более подряд разблокировки)?
...
Рейтинг: 0 / 0
Помогите составить запрос
    #35358350
postuser
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Все перечисленные ситуации возможны.
...
Рейтинг: 0 / 0
Помогите составить запрос
    #35358560
Бабичев Сергей
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Вот тебе кусок кода (на уровне идеи подхода к решению поставленной тобой задачи) для "подумать".
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
select id, min(lock_date) as lock_date, unlock_date
  from (
         select a0.id, a0.date_ as lock_date,
                (
                  select min(a1.date)
                    from action a1
                   where a1.action = 't'
                     and a0.id = a1.id
                     and a0.date < a1.date
                ) as unlock_date
           from action a0
          where a0.action = 'f'
       ) v
 group by id, unlock_date

Данный запрос в пределах одной записи результирующего набора данных для каждого пользователя вернет дату начала блокировки и дату окончания блокировки. Если пользователя заблокировали, а разблокировать забыли, то в качестве даты окончания блокировки вернется NULL. Если у абонента было несколько циклов блокировки/разблокировки, то для него вернется несколько строк.
Осталось немного - найти разность дат в днях, сделать группировку по каждому пользователю, просчитав сумму полученных разностей. Ну и наложить условия на выборку на предмет попадания диапазонов блокировки/разблокировки в интересуемый период времени.
Уж доработку напильником сделай сам...
...
Рейтинг: 0 / 0
Помогите составить запрос
    #35358569
Бабичев Сергей
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Бабичев СергейВот тебе кусок кода (на уровне идеи подхода к решению поставленной тобой задачи) для "подумать".
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
select id, min(lock_date) as lock_date, unlock_date
  from (
         select a0.id, a0.date_ as lock_date,
                (
                  select min(a1.date)
                    from action a1
                   where a1.action = 't'
                     and a0.id = a1.id
                     and a0.date < a1.date
                ) as unlock_date
           from action a0
          where a0.action = 'f'
       ) v
 group by id, unlock_date

Данный запрос в пределах одной записи результирующего набора данных для каждого пользователя вернет дату начала блокировки и дату окончания блокировки. Если пользователя заблокировали, а разблокировать забыли, то в качестве даты окончания блокировки вернется NULL. Если у абонента было несколько циклов блокировки/разблокировки, то для него вернется несколько строк.
Осталось немного - найти разность дат в днях, сделать группировку по каждому пользователю, просчитав сумму полученных разностей. Ну и наложить условия на выборку на предмет попадания диапазонов блокировки/разблокировки в интересуемый период времени.
Уж доработку напильником сделай сам...
Очепятка, однако... :)
Читать как:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
select id, min(lock_date) as lock_date, unlock_date
  from (
         select a0.id, a0.date as lock_date,
                (
                  select min(a1.date)
                    from action a1
                   where a1.action = 't'
                     and a0.id = a1.id
                     and a0.date < a1.date
                ) as unlock_date
           from action a0
          where a0.action = 'f'
       ) v
 group by id, unlock_date
...
Рейтинг: 0 / 0
Помогите составить запрос
    #35358799
Andrey Daeron
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Как альтернативная мысль:
ИМХО тут уже можно и про plpgsql процедуру подумать, вполне может быть, что она будет быстрее чем вложенные подзапросы. Процедура по идее не сложная.
...
Рейтинг: 0 / 0
7 сообщений из 7, страница 1 из 1
Форумы / PostgreSQL [игнор отключен] [закрыт для гостей] / Помогите составить запрос
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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