powered by simpleCommunicator - 2.0.53     © 2025 Programmizd 02
Форумы / Microsoft SQL Server [игнор отключен] [закрыт для гостей] / И снова про наложение интервалов дат
23 сообщений из 23, страница 1 из 1
И снова про наложение интервалов дат
    #39997579
edward_sh
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Добрый день!
Имеется на сервере 2008 R2 таблица вида (все поля типа date):
Курс_Начало
Курс_конец

Очно1_Начало
Очно1_Конец
Очно2_Начало
Очно2_Конец
Заочно_Начало
Заочно_Конец
Удал_Начало
Удал_Конец

Отделенные столбцы могут содержать закрытые даты (т.е. начало и конец), либо иметь значение NULL, если этот этап не предусмотрен. Однако минимум один этап должен быть( или несколько). Четкого порядка следования этапов нет, т.е. может быть сначала очная часть, а потом заочная, а может быть и наоборот.
Требуется при вставке (обновлении) записи проверять, чтобы эти диапазоны дат не пересекались между собой.
Т.е. кончился один период, начался со следующего дня другой. Период может перетекать на другой год. Например, период обучения начался 01.12.2019 окончился 02.03.2020.
Если все даты не пересекаются, в качестве "вишенки" на торт надо взять самую раннюю дату начала периода как начало_курса, а самую крайнюю дату окончания периода взять как курс_конец.
Проблема еще заключается и в том, что вводимые даты могут быть не привязаны к текущему году.
Например, при вводе в 2020 году курса на 2021 год (типа планирование вперед), или же на 2013 год (восстанавливаем историю).
Тупо перебирать каждую дату и сравнивать ее с остальными? И как сравнивать существующую дату периода с NULL значением другого периода?
...
Рейтинг: 0 / 0
И снова про наложение интервалов дат
    #39997583
andreymx
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
и таблицу не забудьте заблокировать... а то две параллельные сессии мало что смогут наделать
...
Рейтинг: 0 / 0
И снова про наложение интервалов дат
    #39997585
edward_sh
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
andreymx,

Проверка будет проводиться в триггерах INSTEAD OF, поэтому все остальные встанут в очередь (я полагаю так :) )
...
Рейтинг: 0 / 0
И снова про наложение интервалов дат
    #39997597
aleks222
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
edward_sh
Добрый день!
Имеется на сервере 2008 R2 таблица вида (все поля типа date):
Курс_Начало
Курс_конец

Очно1_Начало
Очно1_Конец
Очно2_Начало
Очно2_Конец
Заочно_Начало
Заочно_Конец
Удал_Начало
Удал_Конец

Тупо перебирать каждую дату и сравнивать ее с остальными? И как сравнивать существующую дату периода с NULL значением другого периода?


Есть у революции начало - нет у революции конца.

Не пишите концов и минует вас геморрой.

Если хорошенько подумать, то недопустимы не только наложения, но и разрывы.

Очно1_Начало
Отчислен1_Начало
Очно2_Начало
Отчислен2_Начало
Заочно_Начало
Отчислен2_Начало
Удал_Начало
УжеНЕУдал_Начало


Пересечения невозможны, разрывы невозможны.
Проверять ничего не надо.
...
Рейтинг: 0 / 0
И снова про наложение интервалов дат
    #39997607
edward_sh
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Aleks222
Это график обучения по фазам одного курса.
Поэтому у одной фазы ДОЛЖНО быть как начало, так и конец.
Следующая фаза (если она есть) наступает на следующий день (если нет выходных), если есть выходные, то наступает разрыв в сроках фаз на эти дни.
Проверять на пересечение интервалов фаз необходимо. Ибо нельзя себе представить, что человек находится на дистанционном обучении и тут же присутствует лично. Это не предусмотрено планом-графиком обучения.
...
Рейтинг: 0 / 0
И снова про наложение интервалов дат
    #39997619
Фотография Akina
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
edward_sh
Тупо перебирать каждую дату и сравнивать ее с остальными?

Зачем? Отсортировать по началам и сверять конец и LEAD(начало).
edward_sh
И как сравнивать существующую дату периода с NULL значением другого периода?
Если запись с двумя NULL - просто игнорировать её существование. Если с одним - с учётом описанного скорее всего это следует интерпретировать как ошибку в данных.
...
Рейтинг: 0 / 0
И снова про наложение интервалов дат
    #39997649
aleks222
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
edward_sh
Aleks222
Это график обучения по фазам одного курса.
Поэтому у одной фазы ДОЛЖНО быть как начало, так и конец.
Следующая фаза (если она есть) наступает на следующий день (если нет выходных), если есть выходные, то наступает разрыв в сроках фаз на эти дни.
Проверять на пересечение интервалов фаз необходимо. Ибо нельзя себе представить, что человек находится на дистанционном обучении и тут же присутствует лично. Это не предусмотрено планом-графиком обучения.


Тупость неизлечима.
...
Рейтинг: 0 / 0
И снова про наложение интервалов дат
    #39997879
edward_sh
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Формат строки записи может быть таким
01.02.2020 01.03.2020 NULL NULL NULL NULL 01.02.2020 01.03.2020 NULL NULL
01.01.2020 14.03.2020 02.03.2020 14.03.2020 NULL NULL 01.01.2020 28.02.2020 NULL NULL
и т.д.
Поэтому игнорировать строки со значением NULL не получится
...
Рейтинг: 0 / 0
И снова про наложение интервалов дат
    #39997880
edward_sh
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Забыл добавить, что проверка пересечения интервалов нужно проводить в пределах одной строки (записи)
...
Рейтинг: 0 / 0
И снова про наложение интервалов дат
    #39997890
aleks222
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
edward_sh
Формат строки записи может быть таким
01.02.2020 01.03.2020 NULL NULL NULL NULL 01.02.2020 01.03.2020 NULL NULL
01.01.2020 14.03.2020 02.03.2020 14.03.2020 NULL NULL 01.01.2020 28.02.2020 NULL NULL
и т.д.
Поэтому игнорировать строки со значением NULL не получится


Ну это, ваще, клинический случай. Медицина тут бессильна.
...
Рейтинг: 0 / 0
И снова про наложение интервалов дат
    #39997950
Сотрудник Главного Управления
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
edward_sh
если есть выходные, то наступает разрыв в сроках фаз на эти дни.

Если так сильно нужен разрыв
сделайте такую логику:
Разрыв_Начало
И этот разрыв окончится с наступлением следующего состояния.
...
Рейтинг: 0 / 0
И снова про наложение интервалов дат
    #39998018
edward_sh
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
To aleks222
Перестав причитать про свое клиническое состояние психики - по делу сказать (посоветовать) есть что?
Вроде простая задача - проверить столбцы дат одной записи на пересечение интервалов времени, а сколько советов не в тему...
Мне не нужно принудительно делать разрывы и т.д. Нужно только ПРОВЕРИТЬ интервалы.
...
Рейтинг: 0 / 0
И снова про наложение интервалов дат
    #39998033
invm
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
edward_sh,

Проблема в том, что вы решаете задачу не как разработчик БД, а так, как заполняли бы вручную соответствующую бумажную форму.
Отсюда и кривая модель данных и желание заносить концы интервалов.

Проверять пересечения не нужно.
Нужно иметь дату начала курса, дату окончания курса, даты начал этапов (кроме первого) и производственный календарь. Тогда даты окончаний этапов просто рассчитываются.

Но если очень хочется извращений с проверками, то вот вам пример реализации
Код: 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.
declare @t table (ds1 date, de1 date, ds2 date, de2 date);

insert into @t
values
 ('20200901', '20200911', '20200903', '20200920'),
 ('20201002', '20201012', '20201015', '20201025'),
 ('20201103', '20201130', '20201115', '20201125'),

 ('20190901', '20190911', '20200903', '20200920'),
 ('20181002', '20181012', '20201015', '20201025'),
 ('20171103', '20171130', '20201115', '20201125');

/*Есть пересекающиеся интервалы*/
select
 a.*
from
 @t a outer apply
 (
  select top (1)
   c.f
  from
   (select f, (row_number() over (order by d) - 1) % 2 as rn from (values (a.ds1, 0), (a.de1, 1), (a.ds2, 0), (a.de2, 1)) b(d, f)) c(f, rn)
  where
   c.f <> c.rn
 ) d(f)
where
 d.f is not null;



ЗЫ: К тому же, если уж проверяете корректность данных, то нужно проверять все, в том числе и отсутствие невалидных разрывов между концом одного этапа и начало следующего.
...
Рейтинг: 0 / 0
И снова про наложение интервалов дат
    #39998038
aleks222
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
invm
Но если очень хочется извращений с проверками, то вот вам пример реализации


Вангую, слабовато будет.

edward_sh
Формат строки записи может быть таким
01.02.2020 01.03.2020 NULL NULL NULL NULL 01.02.2020 01.03.2020 NULL NULL
01.01.2020 14.03.2020 02.03.2020 14.03.2020 NULL NULL 01.01.2020 28.02.2020 NULL NULL
и т.д.
Поэтому игнорировать строки со значением NULL не получится
...
Рейтинг: 0 / 0
И снова про наложение интервалов дат
    #39998040
Сотрудник Главного Управления
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
edward_sh
Нужно только ПРОВЕРИТЬ интервалы.

а, и всего лишь ?

тогда вам поможет следующее утверждение:

Даны два полуоткрытых числовых интервала [ A; B ) и [ X; Y )

Указанные интервалы имеют непустое пересечение тогда и только тогда , когда является истинным следующее логическое выражение:

( (X >= A) И (X < B) ) ИЛИ ( (A >= X) И (A < Y) )
...
Рейтинг: 0 / 0
И снова про наложение интервалов дат
    #39998077
SERG1257
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
была у меня похожая задача только структура была немного другой
Код: sql
1.
2.
3.
4.
create table prog_person_link (prog_person_link_id int primary key,
 person_id int references person,
 program_id int references program,
 dfrom datetime not null, dto datetime not null, check dfrom<dto)


dto в базе хранилась как "волшебная" дата в будущем 99990101 клиенту показывалась как null
dto предыдущего периода всегда был на секунду раньше следующего dfrom то бишь разрывы в секунду были по определению

Чтобы определить есть ли для записи пересечение интервалов у конкретного person_id

Код: sql
1.
2.
3.
4.
select (select count(*) from prog_person_link l2
        where l2.person_id=l1.person_id and l1.prog_person_link_id<>l2.prog_person_link_id
         and not (l1.dto < l2.dfrom or l2.dto<l1.dfrom)) as cnt
 from prog_person_link l1 where person_id=@person_id



Сотрудник Главного Управления Даны два полуоткрытых числовых интервала [ A; B ) и [ X; Y )Если заведомо A<B и X<Y
то интервалы не пересекаются если B<X или Y<A
В такой формулировке звучало попроще и понятнее.
...
Рейтинг: 0 / 0
И снова про наложение интервалов дат
    #39998092
edward_sh
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Добрый вечер, уважаемы доны и доньи!
Когда интервал времени А заведомо ранее интервала Б - задача простая и легкая.
У меня несколько неопределенность - интервал А может быть меньше, а может быть больше интервала Б.
Тут еще вмешиваются интервалы В,Г и т.д.
Может быть стоит развернуть строку записи в столбцы временной таблицы, а там уже по накатанному пути искать пересечение дат?
...
Рейтинг: 0 / 0
И снова про наложение интервалов дат
    #39998094
SERG1257
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
edward_sh Тут еще вмешиваются интервалы В,Г и т.дЧто значит и т.д? У вас четыре, только четыре и никогда не может быть более четырех интервалов. (по дизайну базы)
Решайте задачу "в лоб" способом который предложил я или Сотрудник Главного Управления
берете первый интервал и сравниваете со вторым, третьим и четвертым
берете второй интервал и сравниваете с третьим и четвертым
берете третий интервал и сравниваете с четвертым.
...
Рейтинг: 0 / 0
И снова про наложение интервалов дат
    #39998096
invm
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
edward_sh
Может быть стоит развернуть строку записи в столбцы временной таблицы, а там уже по накатанному пути искать пересечение дат?
Главное - не читайте ответы. Тогда точно все получится.
...
Рейтинг: 0 / 0
И снова про наложение интервалов дат
    #39998097
iap
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Отрезок AB (A<=B) пересекается с отрезком XY (X<=Y) ,
если A<=Y & B>=X .
И ничего тут вмешаться не может.
Не имеет значения также, какой отрезок длиннее,
находится ли один отрезок целиком в другом (это, разумеется, частный случай пересечения) и т.д
...
Рейтинг: 0 / 0
И снова про наложение интервалов дат
    #39998411
edward_sh
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
To invm:
Ваш метод мне понравился, буду пробовать допилить его под свои проблемы.

Джентельмены!
В процессе обсуждения моего вопроса, я услышал от гуру и не только соображения о моем интеллекте и кривизне рук при проектировании таблицы. Не сочтите за труд, снизойдите до моего уровня и растолкуйте, что я сделал в этой таблице не так с Вашей точки зрения. Это поможет мне избежать проблем в будущем.
Однако, хочу заметить сразу, предложенная версия работы с таблицей-календарем становится очень сомнительной по причинам:
1 - отсутствует администратор БД, который бы подгружал актуальный календарь (кстати, где его взять?)
2 - заполнять БД будут тетеньки-пенсионерки, расскажите им про все это ...
3 - где взять календарь на 2010-2013 год?
4 - Мне предлагают, вместо ПРОСТОГО введения дата начала/ конца (и на этом все) завести дополнительные таблицы, актуальность которых необходимо поддерживать, строить сложные запросы.
5 - Данные будет вводить тетенька, далекая от высоких технологий.
6 - Интервалы между фазами обучения меня не волнуют - это проблемы ввода
7 - Все более-менее укладывалось в схему, пока не наступил КОВИД, после чего, очную часть фаз обучения перенесли на пару месяцев вперед.
8 - Если действовать как предлагали некоторые, начало следующего периода - это окончание предыдущего, возникает вопрос - что делали эти два месяца слушатели? Учились или гоняли балду? Оплата из госбюджета идет по факту.


Если возникли вопросы по этим пунктам - отвечу...

PS: сейчас около 10 курсов по бюждету и около 20 по внебюджету....
...
Рейтинг: 0 / 0
И снова про наложение интервалов дат
    #39998548
SERG1257
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
edward_sh растолкуйте, что я сделал в этой таблице не так с Вашей точки зренияТы развернул в строчку то, что должно быть другими строками. Это не то чтобы прямо совсем неправильно, это быстро дешево и сердито. Однако такая структура плохо переносит изменения (где четыре интервала, там и пятый), очень неудобна для написания проверок типа CHECK (посмотри на мою инструкцию, а потом напиши ее для пятого интервала)
Далее идет деткий лепет
edward_sh 1 - отсутствует администратор БД, который бы подгружал актуальный календарь
Во-первых не дело администратору БД подгружать календарь. Это дело администратора приложения. Две должности могут совмещатся в одном человеке, но разделять их необходимо.
Во-вторых какое НАМ дело на то, что у вас отсутствует или присутсвует. Считаете что такая должность нужна - выбивайте ставку.
edward_sh 2 - заполнять БД будут тетеньки-пенсионерки, расскажите им про все это ...Не мы, а вы (с) Приключения Шурика
Проблемы индейцев шерифа не волнуют.

edward_sh 7 - Все более-менее укладывалось в схему, пока не наступил КОВИД, после чего, очную часть фаз обучения перенесли на пару месяцев вперед.Что и требовалось доказать.

edward_sh Если действовать как предлагали некоторые, начало следующего периода - это окончание предыдущегоЭто один из вариантов решения. Разрыв по сути будет еще одним интервалом со статусом - ничего. У такой схемы тоже есть достоинства и недостатки. Если вы не видите достоинств - не применяйте. Но изучить ее (схему) имеет смысл.

edward_sh PS: сейчас около 10 курсов по бюждету и около 20 по внебюджету.... что бы это значило.
...
Рейтинг: 0 / 0
И снова про наложение интервалов дат
    #39998588
edward_sh
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
TO SERG1257:
До появления мысли использовать триггер INSTEAD OF, CHECK'ами проверялось только то, чтобы дата начала фаза была меньше даты окончания. С появлением триггера это будет проще сделать в одном месте, что не отменяет контроль CHECK.
Была первоначальная идея, как советовали здесь, уместить все интервалы в одной таблице. После некоторых раздумий я отказался от этого, (может быть зря?) время покажет. Еще есть время перекроить таблицу. Также рассматривался вариант с созданием отдельной таблицы для каждой фазы обучения. Накладные расходы: создание и ведение актуальности дополнительных таблиц, сложные запросы с Join и т.д. При моей, вроде не лучшей схеме, я делаю ОДИН простой select и вуаля, передо мной ПОЛНАЯ картина с раскладками всех дат, ничего вычислять не надо, все перед глазами. Тетенька все равно будет вводить все даты в форме, с бумажного листа. Зачем делать лишние движения и вычисления, если все данные идут прямо в руки?
По поводу сохранения только начальных дат и таблицы календаря - я несколько не понял все-таки, при перерыве в фазах обучения как в этом случае узнать срок одного периода?
Например, есть запись интервалов (даты взяты с потолка просто как примеры)

01.01.2020 01.02.2020 03.02.2020 04.03.2020 08.03.2020 15.03.2020 - так было, все ясно и понятно
01.01.2020 01.02.2020 07.05.2020 08.06.2020 10.06.2020 17.06.2020 - так стало, тоже все ясно и понятно

Как в первом и во втором случае работает вариант с календарем? Можно ли однозначно сказать где начинается и оканчивается каждая фаза?
...
Рейтинг: 0 / 0
23 сообщений из 23, страница 1 из 1
Форумы / Microsoft SQL Server [игнор отключен] [закрыт для гостей] / И снова про наложение интервалов дат
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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