|
|
|
Непересекающиеся интервалы
|
|||
|---|---|---|---|
|
#18+
Добрый день уважаемые участники форума! Подскажтье как лучше разрулить такую проблему. Есть таблица EntityTable(ID number, BeginDate DATE, EndDate DATE). Надо чтобы разные сущности не пересекались по периуду действия BeginDate, EndDate. Минимальная гранулярность дат - один день. Как лучше сделать? Есть мысль сделать дополнительную такую табличку EnUseDay(ID number, UseDate DATE) куда для каждого дня в которые действует сущность вставлять строчку. Так данных побольше будет, но и надежнее. ИМХО, конечно. Покритикуйте плиз подход. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 15.09.2011, 15:05 |
|
||
|
Непересекающиеся интервалы
|
|||
|---|---|---|---|
|
#18+
А почему бы не убрать даты начала и конца вообще? Оставить только время действия. Времена действия сущностей считать строго последовательными или разрывы между ними заполнять "псевдосущностью". Posted via ActualForum NNTP Server 1.4 ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 15.09.2011, 15:39 |
|
||
|
Непересекающиеся интервалы
|
|||
|---|---|---|---|
|
#18+
Dimitry Sibiryakov, Быстро же тут отвечают. ) Спасибо за ответ. Про "псевдосущность" не подумал, но есть проблема, что сущности могут быть удалены. Появяться разрыва. Хотя разрывы можно заполнять "псевдосущностями" конечно. Но как будет выглядеть запросы к такой табле? Например, вывести список сущностей действоваших в период с 01.01.2011 по 31.01.2011? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 15.09.2011, 16:11 |
|
||
|
Непересекающиеся интервалы
|
|||
|---|---|---|---|
|
#18+
khus-2011Например, вывести список сущностей действоваших в период с 01.01.2011 по 31.01.2011? Придётся оконные функции задействовать чтобы вычислять сумму длительностей с нарастающим итогом. Posted via ActualForum NNTP Server 1.4 ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 15.09.2011, 16:22 |
|
||
|
Непересекающиеся интервалы
|
|||
|---|---|---|---|
|
#18+
Ну или убрать у сущности дату окончания действия и считать, что она действует пока ей на замену не придёт следующая. Запросы будут чуть попроще. Или вообще не париться и проверять непересечение интервалов триггерами при вставке/изменении, блокируя от записи на это время всю таблицу. Это если модификаций мало. Posted via ActualForum NNTP Server 1.4 ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 15.09.2011, 17:06 |
|
||
|
Непересекающиеся интервалы
|
|||
|---|---|---|---|
|
#18+
Ну не все так мрачно Во первых наложите ограничение BeginDate <= EndDate Во вторых желательно (чтобы упростить запросы и не писать isnull(EndDate,'9999')) сделать EndDate not null default far_in_future Далее пересечение интервалов возможно при четырех условиях Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. Код: plaintext 1. 2. 3. 4. 5. 6. where NOT exists (select * from EntityTable t2 on t1.Entity_id=t2.Entity_id and ( (t1.BeginDate < t2.BeginDate and t1.EndDate<t2.EndDate) or (t2.BeginDate < t1.BeginDate and t2.EndDate<t1.EndDate) ) ) авторНапример, вывести список сущностей действоваших в период с 01.01.2011 по 31.01.2011? опять же либо пересекаемся с интервалом 01.01.2011 по 31.01.2011 Код: plaintext 1. 2. 3. 4. либо не выводить сущьности не пересекающиеся с интервалом Код: plaintext 1. 2. 3. Конечно использовать одну дату change_date вместо BeginDate, EndDate менее избыточно, а стало быть менее противоречиво, но во первых для получения сущностей на произвольную дату требуется два прохода по таблице, во вторых дай первую запись (select top 1 ... в MSSQL или select ... where rownum=1 в оракле) не стандартизирована и в каждой субд реализована по своему. Короче, как всегда, можно оптимизировать либо чтение либо запись ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 15.09.2011, 18:57 |
|
||
|
Непересекающиеся интервалы
|
|||
|---|---|---|---|
|
#18+
SERG1257Либо же интервалы НЕ пересекаются если соблюдается условия Код: plaintext 1. 2. 3. 4. 5. Условие записано неверно. Интервалы НЕ пересекаются при соблюдении следующих условий: Код: plaintext 1. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 16.09.2011, 09:48 |
|
||
|
Непересекающиеся интервалы
|
|||
|---|---|---|---|
|
#18+
khus-2011Добрый день уважаемые участники форума! Подскажтье как лучше разрулить такую проблему. Есть таблица EntityTable(ID number, BeginDate DATE, EndDate DATE). Надо чтобы разные сущности не пересекались по периуду действия BeginDate, EndDate. Минимальная гранулярность дат - один день. Как лучше сделать? Есть мысль сделать дополнительную такую табличку EnUseDay(ID number, UseDate DATE) куда для каждого дня в которые действует сущность вставлять строчку. Так данных побольше будет, но и надежнее. ИМХО, конечно. Покритикуйте плиз подход. А надо...это при выборке или при вставке? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 16.09.2011, 10:01 |
|
||
|
Непересекающиеся интервалы
|
|||
|---|---|---|---|
|
#18+
Всем спасибо за ответы, уважаемые!! ) Озверинkhus-2011Добрый день уважаемые участники форума! Подскажтье как лучше разрулить такую проблему. Есть таблица EntityTable(ID number, BeginDate DATE, EndDate DATE). Надо чтобы разные сущности не пересекались по периуду действия BeginDate, EndDate. Минимальная гранулярность дат - один день. Как лучше сделать? Есть мысль сделать дополнительную такую табличку EnUseDay(ID number, UseDate DATE) куда для каждого дня в которые действует сущность вставлять строчку. Так данных побольше будет, но и надежнее. ИМХО, конечно. Покритикуйте плиз подход. А надо...это при выборке или при вставке?Ну надо, чтобы в таблице не было пересечений. Это выходит при выборке и вставке, вместе наверно. Подробнее задача такая. Требуется исключить малейшую возможность пересечения строк по интервалам. При конкурентном доступе есть небольшая вероятность, что по интервалам это может произойти потому, что одна сессия не видит данных другой сессии до коммита. Используется Оракл. Блокировать всю таблицу не вариант. А если делать вставку в отдельную таблицу то этого произойти не может, не даст первичный ключ этому произойти. Поправте если неправ я с СУБД недавно работаю. Кстати я с начала думал что для каждого дня вставлять строку это дорого обойдется а для нескольких лет мгновенно делается не больше 16 милисекуню. Надо несколько из нескольких тредов проверить как это выглядеть будет. авторНаписать запросы будет домашним заданиемЭто даже такой двоишнег как я сделает ))) SELECT * FROM ENTITYTABLE ET WHERE ET.BEGINDATE BETWEEN '2011-01-01' AND '2011-01-31' OR ET.ENDDATE BETWEEN '2011-01-01' AND '2011-01-31' Это так за январь выбираем _VVP_SERG1257Либо же интервалы НЕ пересекаются если соблюдается условия Код: plaintext 1. 2. 3. 4. 5. Условие записано неверно. Интервалы НЕ пересекаются при соблюдении следующих условий: Код: plaintext 1. ET1.BEGINDATE BETWEEN ET2.BEGINDATE AND ET2.ENDDATE OR ET1.ENDDATE BETWEEN ET2.BEGINDATE AND ET2.ENDDATE Если not добавить то получим непересечения интервалов ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 16.09.2011, 12:37 |
|
||
|
Непересекающиеся интервалы
|
|||
|---|---|---|---|
|
#18+
khus-2011Всем спасибо за ответы, уважаемые!! ) Озверинпропущено... А надо...это при выборке или при вставке?Ну надо, чтобы в таблице не было пересечений. Это выходит при выборке и вставке, вместе наверно. Подробнее задача такая. Требуется исключить малейшую возможность пересечения строк по интервалам. При конкурентном доступе есть небольшая вероятность, что по интервалам это может произойти потому, что одна сессия не видит данных другой сессии до коммита. Используется Оракл. Блокировать всю таблицу не вариант. А если делать вставку в отдельную таблицу то этого произойти не может, не даст первичный ключ этому произойти. Поправте если неправ я с СУБД недавно работаю. Кстати я с начала думал что для каждого дня вставлять строку это дорого обойдется а для нескольких лет мгновенно делается не больше 16 милисекуню. Надо несколько из нескольких тредов проверить как это выглядеть будет. авторНаписать запросы будет домашним заданиемЭто даже такой двоишнег как я сделает ))) SELECT * FROM ENTITYTABLE ET WHERE ET.BEGINDATE BETWEEN '2011-01-01' AND '2011-01-31' OR ET.ENDDATE BETWEEN '2011-01-01' AND '2011-01-31' Это так за январь выбираем _VVP_пропущено... Условие записано неверно. Интервалы НЕ пересекаются при соблюдении следующих условий: Код: plaintext 1. ET1.BEGINDATE BETWEEN ET2.BEGINDATE AND ET2.ENDDATE OR ET1.ENDDATE BETWEEN ET2.BEGINDATE AND ET2.ENDDATE Если not добавить то получим непересечения интервалов Я так и не понял, что в итоге вы будете делать после выборки?) Править данные, которые ранее были уже сохранены пользователям?) Ну да ладно.это на вашей советсти..хохмы ради предложу свой вариант))) Для "хохмы" потребуется доп таблица, которая только нормализует вашу базу, впринципе ) Справочник дней (дат), начиная с даты по умолчанию(1970 год 01.01 например) последовательно: Calendar id | date Код: plaintext 1. 2. 3. 4. 5. 6. этот запрос нам дает в итоге множество "дат" для каждой сущности :) остается сгруппировать коды по кол-ву "дат" >1 Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. выборка все сущностей у которых пересекаются периоды:) запрос мягко говоря не оптимизирован :) но можно достаточно легко оптмизировать ) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 16.09.2011, 13:39 |
|
||
|
Непересекающиеся интервалы
|
|||
|---|---|---|---|
|
#18+
Озверин, не..надо было мне лучше думать ) неправильно выше) сегодня я какую то ахинею пишу ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 16.09.2011, 13:55 |
|
||
|
Непересекающиеся интервалы
|
|||
|---|---|---|---|
|
#18+
Озверин, Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. Выборка только пересекающихся сущностей. Можно перед EXISTS NOT и тогда выборка по только Не пересекающимся будет :) Вроде глянул - логически корректно ) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 16.09.2011, 14:52 |
|
||
|
Непересекающиеся интервалы
|
|||
|---|---|---|---|
|
#18+
Озверин, Вроде да логично, но мне надо чтобы ни при каких обстоятельствах в данных не возникло пересекающихся по датам интервалов, а не выборка только пересекающихся сущностей. Я своим ответом выше только сбил с толку, сорри. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 16.09.2011, 15:27 |
|
||
|
Непересекающиеся интервалы
|
|||
|---|---|---|---|
|
#18+
Вот этот вариант почти подходит Dimitry SibiryakovНу или убрать у сущности дату окончания действия и считать, что она действует пока ей на замену не придёт следующая. Запросы будут чуть попроще.Только у меня возможно "пробелы" в периодах действия. Ну наверное можно выкрутиться как нить, фиктивные записи сделать или еще как. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 16.09.2011, 15:31 |
|
||
|
Непересекающиеся интервалы
|
|||
|---|---|---|---|
|
#18+
khus-2011Вот этот вариант почти подходит Dimitry SibiryakovНу или убрать у сущности дату окончания действия и считать, что она действует пока ей на замену не придёт следующая. Запросы будут чуть попроще.Только у меня возможно "пробелы" в периодах действия. Ну наверное можно выкрутиться как нить, фиктивные записи сделать или еще как. Захотелось вернуться в начало, таблица сущностей имеет уникальный ключ? Таблица сущностей имеет вид: id, begin_date, end_date - где id - уникальный ключ? я в самом деле не понимаю, что вы просите, если - авторПри конкурентном доступе есть небольшая вероятность, что по интервалам это может произойти потому, что одна сессия не видит данных другой сессии до коммита - я не улавливаю суть предложения, т.е. вы намекаете, что не можете проверять не пересекаемость диапазонов во время commit`а по это причине и...и что то просите в замен? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 16.09.2011, 17:56 |
|
||
|
|

start [/forum/topic.php?fid=32&msg=37442042&tid=1542017]: |
0ms |
get settings: |
7ms |
get forum list: |
20ms |
check forum access: |
3ms |
check topic access: |
3ms |
track hit: |
162ms |
get topic data: |
11ms |
get forum data: |
3ms |
get page messages: |
70ms |
get tp. blocked users: |
2ms |
| others: | 205ms |
| total: | 486ms |

| 0 / 0 |
