Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / PostgreSQL [игнор отключен] [закрыт для гостей] / Помогите составить запрос / 7 сообщений из 7, страница 1 из 1
05.06.2008, 22:20
    #35358009
сплю
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Помогите составить запрос
Есть таблица
Код: plaintext
1.
2.
3.
4.
5.
action
  id_action int
  id int - ид. клиента
  date timestamp - дата блокировки/разблокировки
  action boolean - 't' - разблокировка, 'f' - блокировка
Это упрощенная таблица блокировок. Нужно получить для заданного месяца кол-во дней, в течении которых клиент был заблокирован.
Заранее спасибо.
...
Рейтинг: 0 / 0
06.06.2008, 05:09
    #35358234
Помогите составить запрос
Как данные представлены в таблице? Всегда ли количество блокировок совпадает с количеством разблокировок? Бывает ли ситуация, когда весь месяц человек был заблокирован? А разблокирован?
...
Рейтинг: 0 / 0
06.06.2008, 06:08
    #35358244
??????????????
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Помогите составить запрос
Еще вопрос - возможно ли ситуация, когда в таблице идут две подряд (в хронологическом порядке) записи с одинаковым типом ACTION (две или более подряд блокировки, две или более подряд разблокировки)?
...
Рейтинг: 0 / 0
06.06.2008, 09:17
    #35358350
postuser
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Помогите составить запрос
Все перечисленные ситуации возможны.
...
Рейтинг: 0 / 0
06.06.2008, 10:34
    #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
06.06.2008, 10:37
    #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
06.06.2008, 11:43
    #35358799
Andrey Daeron
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Помогите составить запрос
Как альтернативная мысль:
ИМХО тут уже можно и про plpgsql процедуру подумать, вполне может быть, что она будет быстрее чем вложенные подзапросы. Процедура по идее не сложная.
...
Рейтинг: 0 / 0
Форумы / PostgreSQL [игнор отключен] [закрыт для гостей] / Помогите составить запрос / 7 сообщений из 7, страница 1 из 1
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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