|
Пересечение значений по диапазонам дат
|
|||
---|---|---|---|
#18+
Ломаю голову и не могу понять как написать запрос. Прошу помочь Есть 2 таблицы одинаковой структуры: create table #Main ( ID_Object int not Null, [Begin_date] date not Null, [End_date] date not Null, Value float Null, primary key(ID_Object, [Begin_date]) ) create table #Second ( ID_Object int not Null, [Begin_date] date not Null, [End_date] date Null, Value float Null, primary key(ID_Object, [Begin_date]) ) Нужна получить таблицу, где все записи из Main + заполнить недостающие диапазоны из Second. И еще в таблице #Second - End_date может быть Null, а в #Main нет. вот пример заполнения и результат, который должен быть. insert into #Main select 1, '20210305', '20210421', 1 union all select 1, '20210601', '20210731', 2 union all select 1, '20210801', '20210810', 3 insert into #Second select 1, '20210101', '20210520', 10 union all select 1, '20210521', '20210715', 20 union all select 1, '20210801', '20211231', 30 insert into #Result select 1, '20210101', '20210304', 10 union all select 1, '20210305', '20210421', 1 union all select 1, '20210422', '20210520', 10 union all select 1, '20210521', '20210530', 20 union all select 1, '20210601', '20210731', 2 union all select 1, '20210801', '20210810', 3 union all select 1, '20210811', '20211231', 30 ... |
|||
:
Нравится:
Не нравится:
|
|||
03.10.2021, 21:36 |
|
Пересечение значений по диапазонам дат
|
|||
---|---|---|---|
#18+
Забыл добавить что в таблицах может быть много записей (миллионы) ... |
|||
:
Нравится:
Не нравится:
|
|||
03.10.2021, 21:37 |
|
Пересечение значений по диапазонам дат
|
|||
---|---|---|---|
#18+
1. Находишь дырки в #Main. 2. Заполняешь их из #Second. Если у тя гарантировано "отсутствие перекрытия диапазонов" в каждой из табличек - ничего особо сложного. ... |
|||
:
Нравится:
Не нравится:
|
|||
04.10.2021, 06:12 |
|
Пересечение значений по диапазонам дат
|
|||
---|---|---|---|
#18+
aleks222, Я же пример привел. Пересекаться могут как угодно две таблицы по датам. ... |
|||
:
Нравится:
Не нравится:
|
|||
04.10.2021, 14:04 |
|
Пересечение значений по диапазонам дат
|
|||
---|---|---|---|
#18+
Да пусть пересекаются. Это-то тут при чём? Вроде Алекс вполне вменяемо алгоритм расписал... а пересечения он имел в виду в пределах одной таблицы, а не двух вместе. ... |
|||
:
Нравится:
Не нравится:
|
|||
04.10.2021, 14:16 |
|
Пересечение значений по диапазонам дат
|
|||
---|---|---|---|
#18+
Akina Да пусть пересекаются. Это-то тут при чём? Вроде Алекс вполне вменяемо алгоритм расписал... а пересечения он имел в виду в пределах одной таблицы, а не двух вместе. Тогда подскажите как находить дырки. Я не понимаю как написать запрос, который найдет дырки и изменят даты у второй таблице так чтобы они заполнили дырки и не получилось пересечения диапазонов. Логику я понимаю, но как сделать такой запрос - не пойму. ... |
|||
:
Нравится:
Не нравится:
|
|||
04.10.2021, 18:12 |
|
Пересечение значений по диапазонам дат
|
|||
---|---|---|---|
#18+
mih.dim1 Akina Да пусть пересекаются. Это-то тут при чём? Вроде Алекс вполне вменяемо алгоритм расписал... а пересечения он имел в виду в пределах одной таблицы, а не двух вместе. Тогда подскажите как находить дырки. Я не понимаю как написать запрос, который найдет дырки и изменят даты у второй таблице так чтобы они заполнили дырки и не получилось пересечения диапазонов. Логику я понимаю, но как сделать такой запрос - не пойму. Код: sql 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20.
... |
|||
:
Нравится:
Не нравится:
|
|||
04.10.2021, 19:59 |
|
Пересечение значений по диапазонам дат
|
|||
---|---|---|---|
#18+
aleks222, вот какой запрос получился в итоге, может кому то полезно будет ;WITH C AS ( SELECT [End_date] AS [Start_Date], LEAD([Begin_date],1,'99991231') OVER(ORDER BY [Begin_date]) AS Stop_date FROM @Main union all select '19000101' [Start_Date], min([Begin_date]) AS Stop_date from @Main ) select S.ID_Object, utils.MaxDate(V.[Start_Date],S.Begin_Date) Begin_Date, utils.MinDate(V.[Stop_Date],S.End_Date) End_Date, S.Value from @Second S inner join ( SELECT DATEADD(day, 1, [Start_Date]) AS [Start_Date], DATEADD(day, -1, Stop_date) Stop_date FROM C WHERE DATEDIFF(day, [Start_Date], Stop_date) > 1 ) V on dbo.Is_Intervals_Cross(V.Start_Date,V.Stop_date, S.Begin_date, S.End_date)=1 union all select ID_Object, Begin_Date, End_Date, Value from @Main order by 2 ... |
|||
:
Нравится:
Не нравится:
|
|||
10.10.2021, 13:35 |
|
Пересечение значений по диапазонам дат
|
|||
---|---|---|---|
#18+
Сначала нашел пустые промежутки, а потом пересечение с ними заполнил из второй таблице. ... |
|||
:
Нравится:
Не нравится:
|
|||
10.10.2021, 13:36 |
|
Пересечение значений по диапазонам дат
|
|||
---|---|---|---|
#18+
mih.dim1 Сначала нашел пустые промежутки, а потом пересечение с ними заполнил из второй таблице . "Что ж такое, были же люди как люди, и вдруг все сразу стали кретины. Парадокс." (ц, Брат-2) ... |
|||
:
Нравится:
Не нравится:
|
|||
10.10.2021, 13:48 |
|
Пересечение значений по диапазонам дат
|
|||
---|---|---|---|
#18+
mih.dim1 aleks222, вот какой запрос получился в итоге, может кому то полезно будет ;WITH C AS ( SELECT [End_date] AS [Start_Date], LEAD([Begin_date],1,'99991231') OVER(ORDER BY [Begin_date]) AS Stop_date FROM @Main union all select '19000101' [Start_Date], min([Begin_date]) AS Stop_date from @Main ) select S.ID_Object, utils.MaxDate(V.[Start_Date],S.Begin_Date) Begin_Date, utils.MinDate(V.[Stop_Date],S.End_Date) End_Date, S.Value from @Second S inner join ( SELECT DATEADD(day, 1, [Start_Date]) AS [Start_Date], DATEADD(day, -1, Stop_date) Stop_date FROM C WHERE DATEDIFF(day, [Start_Date], Stop_date) > 1 ) V on dbo.Is_Intervals_Cross(V.Start_Date,V.Stop_date, S.Begin_date, S.End_date)=1 union all select ID_Object, Begin_Date, End_Date, Value from @Main order by 2 Извини, дарагой. Это может быть полезно только как пример дурного кода. ... |
|||
:
Нравится:
Не нравится:
|
|||
10.10.2021, 17:28 |
|
Пересечение значений по диапазонам дат
|
|||
---|---|---|---|
#18+
aleks222 mih.dim1 aleks222, вот какой запрос получился в итоге, может кому то полезно будет ;WITH C AS ( SELECT [End_date] AS [Start_Date], LEAD([Begin_date],1,'99991231') OVER(ORDER BY [Begin_date]) AS Stop_date FROM @Main union all select '19000101' [Start_Date], min([Begin_date]) AS Stop_date from @Main ) select S.ID_Object, utils.MaxDate(V.[Start_Date],S.Begin_Date) Begin_Date, utils.MinDate(V.[Stop_Date],S.End_Date) End_Date, S.Value from @Second S inner join ( SELECT DATEADD(day, 1, [Start_Date]) AS [Start_Date], DATEADD(day, -1, Stop_date) Stop_date FROM C WHERE DATEDIFF(day, [Start_Date], Stop_date) > 1 ) V on dbo.Is_Intervals_Cross(V.Start_Date,V.Stop_date, S.Begin_date, S.End_date)=1 union all select ID_Object, Begin_Date, End_Date, Value from @Main order by 2 Извини, дарагой. Это может быть полезно только как пример дурного кода. Ну твой код кончено пример эталонного стиля. Написан что максимально было удобно читать. В отличии от твоего мой код выполняет что нужно по задаче. ... |
|||
:
Нравится:
Не нравится:
|
|||
11.10.2021, 08:40 |
|
Пересечение значений по диапазонам дат
|
|||
---|---|---|---|
#18+
Ролг Хупин mih.dim1 Сначала нашел пустые промежутки, а потом пересечение с ними заполнил из второй таблице . "Что ж такое, были же люди как люди, и вдруг все сразу стали кретины. Парадокс." (ц, Брат-2) "Код гавно, но своего нет. Так как ниспускаюсь до простых смертных" Ролг Хупин Максимальный тролль )))) ... |
|||
:
Нравится:
Не нравится:
|
|||
11.10.2021, 08:43 |
|
|
start [/forum/topic.php?fid=46&msg=40103431&tid=1684214]: |
0ms |
get settings: |
11ms |
get forum list: |
16ms |
check forum access: |
4ms |
check topic access: |
4ms |
track hit: |
156ms |
get topic data: |
13ms |
get forum data: |
3ms |
get page messages: |
70ms |
get tp. blocked users: |
2ms |
others: | 16ms |
total: | 295ms |
0 / 0 |