Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Microsoft SQL Server Новый топик    Ответить
 Объединение временных интервалов  [new]
Gizmor
Member

Откуда:
Сообщений: 54
Уважаемые,
прошу помочь вот с такой задачкой.
Есть временные интервалы, последовательно следующие друг за дружкой. Надо вывести объединенные интервалы, при этом если между исходными интервалами промежуток менее 5 минут их надо схлопнуть.
Вот исходная таблица
DECLARE @TAB TABLE
(STime DATETIME,
ETime DATETIME)
INSERT INTO @TAB (STime, ETime) VALUES
('2014-09-01 20:00:00', '2014-09-01 20:05:00'),
('2014-09-01 20:07:00', '2014-09-01 20:15:00'),
('2014-09-01 22:00:00', '2014-09-01 22:05:00'),
('2014-09-01 22:07:00', '2014-09-01 22:15:00')

SELECT * FROM @TAB

В результате должны получить интервалы
DECLARE @TAB1 TABLE
(STime DATETIME,
ETime DATETIME)
INSERT INTO @TAB1 (STime, ETime) VALUES
('2014-09-01 20:00:00', '2014-09-01 20:15:00'),
('2014-09-01 22:00:00', '2014-09-01 22:15:00')

Подскажите идею как это сделать?
18 сен 14, 16:31    [16591592]     Ответить | Цитировать Сообщить модератору
 Re: Объединение временных интервалов  [new]
a_voronin
Member

Откуда: Москва
Сообщений: 4902
Версия SQL Server какая?
18 сен 14, 16:35    [16591605]     Ответить | Цитировать Сообщить модератору
 Re: Объединение временных интервалов  [new]
Gizmor
Member

Откуда:
Сообщений: 54
2008 R2
18 сен 14, 16:47    [16591664]     Ответить | Цитировать Сообщить модератору
 Re: Объединение временных интервалов  [new]
Gizmor
Member

Откуда:
Сообщений: 54
Нашел решение, но мне кажется сложновато, возможно можно проще
DECLARE @TAB1 TABLE
(STime DATETIME,
ETime DATETIME)
INSERT INTO @TAB1 (STime, ETime) VALUES
('2014-09-01 20:00:00', '2014-09-01 20:12:00'),
('2014-09-01 20:14:00', '2014-09-01 20:15:00'),
('2014-09-01 20:25:00', '2014-09-01 20:30:00'),
('2014-09-01 22:00:00', '2014-09-01 22:05:00'),
('2014-09-01 22:07:00', '2014-09-01 22:15:00')

DECLARE @TAB TABLE
(STime DATETIME,
ETime DATETIME)
INSERT INTO @TAB (STime, ETime)
SELECT
	T1.STime,
	CASE WHEN DATEDIFF(MINUTE, T1.ETime, T2.STime) <= 5 THEN T2.ETime ELSE T1.ETime END AS [ETime]
FROM
	@TAB1 T1
	CROSS JOIN @TAB1 T2
WHERE T2.STime >= T1.ETime

SELECT
	[v_begin].[STime],
	[v_end].[ETime]
FROM
	(SELECT
		[STime],
		[ETime],
		ROW_NUMBER() OVER(ORDER BY [STime]) AS rn
	FROM
	(SELECT DISTINCT-- Находим все начала диапазонов с исключением дубликатов:
		[STime],
		[ETime]
	FROM
		(SELECT
			[STime],
			[ETime]
		FROM
			@TAB
		) s1
	WHERE
		NOT EXISTS
		(SELECT
			NULL
		FROM
			(SELECT
				[STime],
				[ETime]
			FROM
				@TAB
			) s2
		WHERE
			(s1.[STime] > s2.[STime]
			AND s1.[STime] <= s2.[ETime]) OR
			(s1.[STime] = s2.[STime]
			AND s1.[ETime] < s2.[ETime])
		)
	) a) v_begin
	LEFT OUTER JOIN
	(SELECT
		[STime],
		[ETime],
		ROW_NUMBER() OVER(ORDER BY [ETime]) AS rn
	FROM
	(SELECT DISTINCT -- Находим все окончания диапазонов с исключением дубликатов:
		[STime],
		[ETime]
	FROM
		(SELECT
			[STime],
			[ETime]
		FROM
			@TAB
		) s1
	WHERE
		NOT EXISTS
		(SELECT
			NULL
		FROM
			(SELECT
				[STime],
				[ETime]
			FROM
				@TAB
			) s2
		WHERE
			(s1.[ETime] <= s2.[ETime]
			AND s1.[STime] > s2.[STime]) OR
			(s1.[ETime] < s2.[ETime]
			AND s1.[ETime] >= s2.[STime])
		)
	) a) v_end
	ON v_begin.rn = v_end.rn
18 сен 14, 16:56    [16591700]     Ответить | Цитировать Сообщить модератору
 Re: Объединение временных интервалов  [new]
LexusR
Member

Откуда: Novosibirsk
Сообщений: 1887
DECLARE @TAB1 TABLE
(STime DATETIME,
ETime DATETIME)
INSERT INTO @TAB1 (STime, ETime) VALUES
('2014-09-01 20:00:00', '2014-09-01 20:12:00'),
('2014-09-01 20:14:00', '2014-09-01 20:15:00'),
('2014-09-01 20:25:00', '2014-09-01 20:30:00'),
('2014-09-01 22:00:00', '2014-09-01 22:05:00'),
('2014-09-01 22:07:00', '2014-09-01 22:15:00')

;WITH t (STime,ETime) AS(
SELECT DISTINCT
            case when t1.STime< t2.STime then t1.STime ELSE t2.STime end as STime
		   ,case when t1.ETime > t2.ETime then t1.ETime ELSE t2.ETime end as ETime
FROM @TAB1 t1
JOIN @TAB1 t2 on
t1.STime<=DATEADD(mi,5,t2.ETime) and t2.STime<=DATEADD(mi,5,t1.ETime))
SELECT STime, ETime FROM t t1
where not exists(
select * from t t2 
where (t1.STime<>t2.STime or t1.ETime<>t2.ETime)
and t1.stime between t2.stime and t2.ETime and t1.etime between t2.STime and t2.etime)
19 сен 14, 12:29    [16595044]     Ответить | Цитировать Сообщить модератору
 Re: Объединение временных интервалов  [new]
BuKTaP
Member

Откуда:
Сообщений: 132
если точно
автор
последовательно следующие друг за дружкой

то должно хватить и этого
SELECT t.STime, t2.ETime FROM @TAB t
JOIN @TAB t2 ON t.STime < t2.ETime AND t.ETime < t2.STime
WHERE DATEADD(mi,5,t.ETime) >= t2.STime
19 сен 14, 17:22    [16596919]     Ответить | Цитировать Сообщить модератору
 Re: Объединение временных интервалов  [new]
BuKTaP
Member

Откуда:
Сообщений: 132
BuKTaP
если точно
автор
последовательно следующие друг за дружкой

то должно хватить и этого
SELECT t.STime, t2.ETime FROM @TAB t
JOIN @TAB t2 ON t.STime < t2.ETime AND t.ETime < t2.STime
WHERE DATEADD(mi,5,t.ETime) >= t2.STime

не читайте мой бред. не совсем правильно понял условие сразу.
19 сен 14, 17:26    [16596951]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft SQL Server Ответить