powered by simpleCommunicator - 2.0.60     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / PostgreSQL [игнор отключен] [закрыт для гостей] / Алгоритм поиска в таблице с датами
15 сообщений из 15, страница 1 из 1
Алгоритм поиска в таблице с датами
    #35684704
NewLine
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Добрый день. Подскажите пожалуйста, может кто искал что-то похожее или...

Есть таблица, в которой есть список адресов с id-ками адреса (id_address) и промежутками времени, когда этот адрес занят.

id----id_address-------date_start--------date_stop
1 -------- 1 ----------- 01.12.2008 -------- 05.12.2008
2 -------- 1 ----------- 15.12.2008 -------- 25.12.2008
3 -------- 1 ----------- 15.01.2009 -------- 23.01.2009
4 -------- 2 ----------- 05.12.2008 -------- 10.12.2008
5 -------- 2 ----------- 11.12.2008 -------- 31.12.2008
6 -------- 3 ----------- 01.12.2008 -------- 18.12.2008
7 -------- 3 ----------- 25.12.2008 --------- 31.12.2008

Мне нужно находить список свободных адресов в определенный промежуток времени и больше определенного кол-ва свободных дней.

Например найти все свободные с 01.12.2008 по 31.12.2009 и кол-во свободных дней больше 5
найдуться id_address - 1, 3.
...
Рейтинг: 0 / 0
Алгоритм поиска в таблице с датами
    #35684832
А почему в итоговую выборку не попала запись
id----id_address-------date_start--------date_stop
5 -------- 2 ----------- 11.12.2008 -------- 31.12.2008
???
Она же и в интервал попала и по длительности больше 5 дней...
...
Рейтинг: 0 / 0
Алгоритм поиска в таблице с датами
    #35684845
А вообще, что-то такое должно быть:
Код: plaintext
1.
2.
3.
4.
select * 
  from t
 where date_stop >= :p_date_start
   and :p_date_stop >= date_start
   and least(date_stop, :p_date_stop) - greatest(date_start, :p_date_start) > :num_day
где:
:p_date_start - параметр, передающий дату начала интересующего интервала,
:p_date_stop - параметр, передающий дату окончания интересующего интервала,
:num_day - параметр, передающий кол-во свободных дней
...
Рейтинг: 0 / 0
Алгоритм поиска в таблице с датами
    #35684881
NewLine
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Добрый Э - Эх
А почему в итоговую выборку не попала запись
id----id_address-------date_start--------date_stop
5 -------- 2 ----------- 11.12.2008 -------- 31.12.2008
???
Она же и в интервал попала и по длительности больше 5 дней...


Она как раз таки не попадает, мне нужны свободные адреса а id_address = 2 занят с 5 по 31 и кол-во свободных дней у него 4(с 1 по 5).

id----id_address-------date_start--------date_stop
4 -------- 2 ----------- 05.12.2008 -------- 10.12.2008
5 -------- 2 ----------- 11.12.2008 -------- 31.12.2008
...
Рейтинг: 0 / 0
Алгоритм поиска в таблице с датами
    #35684905
Тьфу ты, не заметил, что данные в таблице представляют период занятости... :)
Но тогда совсе непонятно условие задачи. Ведь если в таблице указан период занятости, то, стало быть, во всё остальное время адрес свободен. Тогда вообще все записи должны попасть в итоговую выборку...

Вобщем, попробуй сформулировать условие задачи ещё раз, а то лично я уже совсем запутался.
...
Рейтинг: 0 / 0
Алгоритм поиска в таблице с датами
    #35684977
NewLine
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Мне нужно получить список id адресов которые не заняты с 01.12.2008 по 31.12.2008 и с кол-ом свободных дней больше 5. (я в первом посте не тот промежуток задал год 2008)
Получается что id_address = 2 туда не попадает т.к. он занят с 5 по 31
4 -------- 2 ----------- 05.12.2008 -------- 10.12.2008
5 -------- 2 ----------- 11.12.2008 -------- 31.12.2008


а 1 и 3 попадают.
...
Рейтинг: 0 / 0
Алгоритм поиска в таблице с датами
    #35685011
assa
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
NewLine Мне нужно находить список свободных адресов в определенный промежуток времени и больше определенного кол-ва свободных дней.

Например найти все свободные с 01.12.2008 по 31.12.2009 и кол-во свободных дней больше 5
найдуться id_address - 1, 3.задача распадается на 2
1. если теоретически есть накладывающиеся записи по id_address - то "фсё плёхо" (т.е. считать можно, но сложно - надо сливать накладывающиеся диапазоны, и не сливать разрывы)

2. если гарантированно нет пересечений между интервалами занятости адреса, то просто считайте сумму
SUM("date_start"::date - "date_stop"::date) ... GROUP BY id_address
или точнее
Код: plaintext
1.
2.
(- :p_date_start +  :p_date_stop) - SUM("date_start"::date - "date_stop"::date)  ... GROUP BY id_address
HAVING
(- :p_date_start +  :p_date_stop) - SUM("date_start"::date - "date_stop"::date)  >= :p_num_day
в терминах Э-эха
...
Рейтинг: 0 / 0
Алгоритм поиска в таблице с датами
    #35685024
assa1. если теоретически есть накладывающиеся записи по id_address - то "фсё плёхо" (т.е. считать можно, но сложно - надо сливать накладывающиеся диапазоны, и не сливать разрывы)На самом деле - весьма тривиальная задача ;)
...
Рейтинг: 0 / 0
Алгоритм поиска в таблице с датами
    #35685028
assa
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
assa,

да, педант из меня никакой
поменяйте знак у
Код: plaintext
1.
2.
(- :p_date_start +  :p_date_stop) - SUM(- "date_start"::date + "date_stop"::date)  ... GROUP BY id_address
HAVING
(- :p_date_start +  :p_date_stop) - SUM(- "date_start"::date  + "date_stop"::date)  >= :p_num_day
заодно решите для себя, могут ли быть "перепутаны" данные в "date_start" | "date_stop"
...
Рейтинг: 0 / 0
Алгоритм поиска в таблице с датами
    #35685046
assa
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Добрый Э - Эхassa1. если теоретически есть накладывающиеся записи по id_address - то "фсё плёхо" (т.е. считать можно, но сложно - надо сливать накладывающиеся диапазоны, и не сливать разрывы)На самом деле - весьма тривиальная задача ;)возможно и есть простой и быстрый скл, но я предпочел бы сливать на 1 проходе в сортированном наборе (курсоре или FOR _rec IN SELECT ... ORDER BY .... LOOP).
...
Рейтинг: 0 / 0
Алгоритм поиска в таблице с датами
    #35687204
NewLine
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Скажите пожалуйста, а как найти непрерывный интервал между датами...
По такому алгоритму
Код: plaintext
1.
2.
3.
(- :p_date_start +  :p_date_stop) - SUM(- "date_start"::date + "date_stop"::date)  ... GROUP BY id_address
HAVING
(- :p_date_start +  :p_date_stop) - SUM(- "date_start"::date  + "date_stop"::date)  >= :p_num_day

Дни ищутся в разнобой, а нужно чтоб подряд...

Спасибо.
...
Рейтинг: 0 / 0
Алгоритм поиска в таблице с датами
    #35687699
assa
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
NewLineСкажите пожалуйста, а как найти непрерывный интервал между датами...
По такому алгоритму
Код: plaintext
1.
2.
3.
(- :p_date_start +  :p_date_stop) - SUM(- "date_start"::date + "date_stop"::date)  ... GROUP BY id_address
HAVING
(- :p_date_start +  :p_date_stop) - SUM(- "date_start"::date  + "date_stop"::date)  >= :p_num_day

Дни ищутся в разнобой, а нужно чтоб подряд...

Спасибо.скажите, что вы подразумеваете под интервалом между датами?
(в постановке задачи у вас интервал (- "date_start" + "date_stop") задан в записи, и искать его не надо, т.ч. проартикулируйте всю задачу, или все ваши затруднения полностью; возможно - с самого начала).

2. "по такому алгоритму" интервалы не ищутся, а считается разница между параметрическим интервалом и суммой интервалов по данному ид-адреса. (Предложение WHERE на отбор я не приводил - оно набросано у э-эха, там же можно найти поправку на вываливания дат_старт и дат_стоп из диапазона выборки.) Результат сравнивается с параметром отсечки :p_num_day в предложении HAVING. Т.ч. понять вас становится затруднительно.

3. если у вас есть (вернее - допускаются) персечения между интервалами одного и того же адрес-ид, то решать надо иначе. О чем я сразу предупредил.
...
Рейтинг: 0 / 0
Алгоритм поиска в таблице с датами
    #35687961
NewLine
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Под интервалом я понимаю например, есть две записи для одного адреса(id_address = 1)
id----id_address-------date_start--------date_stop
1 -------- 1 ----------- 01.12.2008 -------- 13.12.2008
2 -------- 1 ----------- 15.12.2008 -------- 25.12.2008

У этих двух записей получиться разница 1 свободный день, тобишь 13 число)
И если таких дней по 1 получиться 5 для одного id_ address, то этот адрес попадет в поиск, а не должен...
Вот...
...
Рейтинг: 0 / 0
Алгоритм поиска в таблице с датами
    #35688525
assa
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
NewLineПод интервалом я понимаю например, есть две записи для одного адреса(id_address = 1)
id----id_address-------date_start--------date_stop
1 -------- 1 ----------- 01.12.2008 -------- 13.12.2008
2 -------- 1 ----------- 15.12.2008 -------- 25.12.2008

У этих двух записей получиться разница 1 свободный день, тобишь 13 число)
И если таких дней по 1 получиться 5 для одного id_ address, то этот адрес попадет в поиск, а не должен...
Вот...вы никогда не пробовали формулировать свои мысли не для внутреннего употребления?

читаем
NewLineМне нужно находить список свободных адресов в определенный промежуток времени и больше определенного кол-ва свободных дней.тоже ничего ясного не сказано. не находите?


итак, попробуем проинтуичить:
вам нужны все ид_адресов, для которых, в заданном промежутке дат можно найти хотя бы один сплошной свободный интервал, не менее некоего заданного количества дней.
Так?

тогда я бы сделал ф-ю на plpgsql
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
f( _date_start ,  _date_start, _ndays)
RETURNS
где внутри
  
FOR _rec IN
   SELECT * from t 
          WHERE date_start between (_date_start AND _date_stop)
             OR  date_stop  between (_date_start AND _date_stop)

          ORDER BY id_address, date_start --,date_stop
LOOP
     IF _rec.id_address = _id_address THEN

           IF ....... > _ndays 
              and .... ---проверяем , что не выдали еще
                   RETURN NEXT _rec.id_address
           else
                  ...---заполняем   переменные предыдущей
           END IF;
          
     ELSE 
           _id_address:=_rec.id_address;
     END IF;
END LOOP;
да, а на скл это через подзапрос. болванка примерно такая:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
SELECT --DISTINCT ON(id_address)
*
,
COALESCE(
   SELECT greatest(p.date_stop, _date_start)
     from tab as p 
     WHERE  p.id_address = t.id_address
       AND p.date_stop<=t.date_start
       ORDER BY
                -- p.id_address , --зависит от наличия и структуры индексов
                p.date_stop DESC LIMIT  1 

,_date_start) as date_prev
 from tab as t 
          WHERE date_start between (_date_start AND _date_stop)
              OR  date_stop  between (_date_start AND _date_stop)
              AND date_start - date_prev --тут надо подставить то же выражение что и выше
                 >= _ndays
          ORDER BY id_address, date_start --,date_stop
что будет быстрее - надо смотреть
...
Рейтинг: 0 / 0
Алгоритм поиска в таблице с датами
    #35689876
NewLine
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Спасибо большое assa
А над формулировкой мыслей я поработаю, просто хочется как лучше, но не всегда получается...
...
Рейтинг: 0 / 0
15 сообщений из 15, страница 1 из 1
Форумы / PostgreSQL [игнор отключен] [закрыт для гостей] / Алгоритм поиска в таблице с датами
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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