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

Дана некоторая сущность (ID). У этой сущности в бд хранятся две характеристики (Param1 и Param2). Храняться в разных таблицах. У каждой характеристики есть дата начала и окончания действия (dtBegin, dtEnd). Периоды не пересекаются.

Нужно выбрать из двух таблиц все временные интервалы и сочетания характеристик.

Пример:
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
DECLARE @t1 TABLE ([ID] int, [Param1] varchar(100), [dtBegin] date, [dtEnd] date)

DECLARE @t2 TABLE ([ID] int, [Param2] varchar(100), [dtBegin] date, [dtEnd] date)

INSERT INTO @t1([ID], [Param1], [dtBegin], [dtEnd])
VALUES
(1, 'X', '2000-01-01', '2010-01-12'),
(1, 'Y', '2010-01-13', '9999-01-01')


INSERT INTO @t2([ID], [Param2], [dtBegin], [dtEnd])
VALUES
(1, 'W', '2000-01-01', '2008-09-05'),
(1, 'Q', '2011-09-08', '9999-01-01')



Нужен результат:
Код: sql
1.
2.
3.
4.
1, 'X', 'W', '2000-01-01', '2008-09-05'
1, 'X', NULL, '2008-09-06', '2010-01-12'
1, 'Y', NULL, '2010-01-13', '2011-09-07'
1, 'Y', 'Q', '2011-09-08', '9999-01-01'
...
Рейтинг: 0 / 0
Пересечение временных интервалов
    #39777485
newLoginSql
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Если представить всё это как две временные оси, то нужен срез по обеим. Как-то так:
...
Рейтинг: 0 / 0
Пересечение временных интервалов
    #39777567
aleks222
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
newLoginSqlЕсли представить всё это как две временные оси, то нужен срез по обеим. Как-то так:

См. свою же картинку.

1. Концы всех интервалов образуют последовательность моментов времени.
2. Каждые два последовательных момента времени образуют интервал уникального сочетания характеристик.
3. Отсюда элементарный алгоритм.
...
Рейтинг: 0 / 0
Пересечение временных интервалов
    #39777676
Kopelly
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Код: 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.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
DECLARE @t1 TABLE ([ID] int, [Param1] varchar(100), [dtBegin] date, [dtEnd] date)

DECLARE @t2 TABLE ([ID] int, [Param2] varchar(100), [dtBegin] date, [dtEnd] date)

INSERT INTO @t1([ID], [Param1], [dtBegin], [dtEnd])
VALUES
(1, 'X', '2000-01-01', '2010-01-12'),
(1, 'Y', '2010-01-13', '9999-01-01')


INSERT INTO @t2([ID], [Param2], [dtBegin], [dtEnd])
VALUES
--(1, 'W', '2000-01-01', '2008-09-05'),
--(1, 'Q', '2011-09-08', '9999-01-01');
(1, 'W', '2001-01-01', '2008-09-05'),
(1, 'Q', '2011-09-08', '2015-01-01');


with dates1 as
(Select ID,min(dtBegin) as d1_min,max(dtEnd) as d1_max  From @t1 Group by ID),
dates2 as
(Select ID,min(dtBegin) as d1_min,max(dtEnd) as d1_max  From @t2 Group by ID),
t2_nulls as (
Select * From @t2 --Исходные периоды
Union all --Добавление пустого периода в начале
Select a.ID,null as Param2, 
       a.d1_min as dtBegin,
	   dateadd(d,-1,b.d1_min) as dtEnd 
  From dates1 a
  join dates2  b on a.d1_min<b.d1_min and a.ID = b.ID
Union all --Добавление пустого периода между периодами
Select a.ID,null,
       dateadd(d,1,a.dtEnd) as dtBegin,
	   dateadd(d,-1,(Select min(b.dtBegin) From @t2 b Where a.ID = b.ID and a.dtEnd<b.dtBegin)) as dtEnd 
  From @t2 a 
 Where (Select min(b.dtBegin) From @t2 b Where a.ID = b.ID and a.dtEnd<b.dtBegin) > dateadd(d,1,a.dtEnd)
union all --Добавление пустого периода в конце
Select a.ID,null as Param2, 
       dateadd(d,-1,b.d1_max) as dtBegin,
	   a.d1_max as dtEnd 
  From dates1 a
  join dates2  b on a.d1_max>b.d1_max and a.ID = b.ID)
Select a.ID,
       a.Param1,
	   b.Param2,
	   iif(a.dtBegin>b.dtBegin,a.dtBegin,b.dtBegin) as dtBegin,
	   iif(a.dtEnd<b.dtEnd,a.dtEnd,b.dtEnd) as dtEnd  
 From @t1 a
join t2_nulls b on a.ID = b.ID and a.dtBegin<=b.dtEnd and a.dtEnd>=b.dtBegin
Order by 1,4
...
Рейтинг: 0 / 0
Пересечение временных интервалов
    #39777681
Фотография Щукина Анна
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Kopelly,

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


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