Как решить задачку запросом

1. igormiro 714 16.06.14 23:55 Сейчас в теме
Решение только запросом другие не предлагать.

Вот условие
Измерение1 Дата
P1 02.06.2014
P1 03.06.2014
P1 04.06.2014
P1 10.06.2014
P1 11.06.2014
P1 12.06.2014
P1 17.06.2014
P1 18.06.2014
P1 19.06.2014

Нужно чтобы в итоге было
Измерение ДатаНачало ДатаОкончания
P1 02.06.2014 04.06.2014
P1 10.06.2014 12.06.2014
P1 17.06.2014 19.06.2014
По теме из базы знаний
Вознаграждение за ответ
Показать полностью
Найденные решения
19. adva 45 17.06.14 08:41 Сейчас в теме
Наверное так:

ВЫБРАТЬ
	1 КАК Дата
ПОМЕСТИТЬ Даты

ОБЪЕДИНИТЬ ВСЕ

ВЫБРАТЬ
	2

ОБЪЕДИНИТЬ ВСЕ

ВЫБРАТЬ
	3

ОБЪЕДИНИТЬ ВСЕ

ВЫБРАТЬ
	5

ОБЪЕДИНИТЬ ВСЕ

ВЫБРАТЬ
	6
;

////////////////////////////////////////////////////////////­////////////////////
ВЫБРАТЬ
	Даты.Дата
ПОМЕСТИТЬ ПервыеДатыИнтервалов
ИЗ
	Даты КАК Даты
		ЛЕВОЕ СОЕДИНЕНИЕ Даты КАК ДатыДо
		ПО (ДатыДо.Дата = Даты.Дата - 1)
ГДЕ
	ДатыДо.Дата ЕСТЬ NULL 
;

////////////////////////////////////////////////////////////­////////////////////
ВЫБРАТЬ
	Даты.Дата
ПОМЕСТИТЬ ПоследниеДатыИнтервалов
ИЗ
	Даты КАК Даты
		ЛЕВОЕ СОЕДИНЕНИЕ Даты КАК ДатыПосле
		ПО (Даты.Дата + 1 = ДатыПосле.Дата)
ГДЕ
	ДатыПосле.Дата ЕСТЬ NULL 
;

////////////////////////////////////////////////////////////­////////////////////
ВЫБРАТЬ
	ПервыеДатыИнтервалов.Дата КАК ДатаНач,
	МИНИМУМ(ПоследниеДатыИнтервалов.Дата) КАК ДатаКон
ИЗ
	ПервыеДатыИнтервалов КАК ПервыеДатыИнтервалов
		ВНУТРЕННЕЕ СОЕДИНЕНИЕ ПоследниеДатыИнтервалов КАК ПоследниеДатыИнтервалов
		ПО ПервыеДатыИнтервалов.Дата <= ПоследниеДатыИнтервалов.Дата

СГРУППИРОВАТЬ ПО
	ПервыеДатыИнтервалов.Дата
Показать


Не стал измерения приводить, смысл от этого не меняется
Остальные ответы
В избранное Подписаться на ответы Сортировка: Древо развёрнутое
Свернуть все
2. m-serg74 46 17.06.14 00:13 Сейчас в теме
(1) igormiro, соединение самой с собой по датаслева < датасправа. потом группировка по измерение+датаслева а датасправа минимум
3. m-serg74 46 17.06.14 00:15 Сейчас в теме
+(2) m-serg74, правда непонятно интервал между датами 2 дня? или больше чем 1? или что за условие? от этого зависит дополнительное усложнение запроса
13. igormiro 714 17.06.14 00:43 Сейчас в теме
(2) m-serg74,
От пример твоего решения

ВЫБРАТЬ
	РСведений.Измерение1,
	РСведений.Дата КАК Дата
ПОМЕСТИТЬ Ч
ИЗ
	РегистрСведений.РСведений КАК РСведений
;

////////////////////////////////////////////////////////////­////////////////////
ВЫБРАТЬ
	Ч.Измерение1,
	Ч.Дата КАК Дата,
	МИНИМУМ(Ч1.Дата) КАК Дата1
ИЗ
	Ч КАК Ч
		ЛЕВОЕ СОЕДИНЕНИЕ Ч КАК Ч1
		ПО Ч.Измерение1 = Ч1.Измерение1
			И Ч.Дата < Ч1.Дата

СГРУППИРОВАТЬ ПО
	Ч.Дата,
	Ч.Измерение1

УПОРЯДОЧИТЬ ПО
	Дата
Показать

ответ

P1 02.06.2014 03.06.2014
P1 03.06.2014 04.06.2014
P1 04.06.2014 10.06.2014
P1 10.06.2014 11.06.2014
P1 11.06.2014 12.06.2014
P1 12.06.2014 17.06.2014
P1 17.06.2014 18.06.2014
P1 18.06.2014 19.06.2014
P1 19.06.2014

а нужно 02.06.2014 по 04.06.2014
10.06.2014 по 12.06.2014
17.06.2014 по 19.06.2014
14. m-serg74 46 17.06.14 00:45 Сейчас в теме
(13) igormiro, а вместо
ПО Ч.Измерение1 = Ч1.Измерение1
И Ч.Дата < Ч1.Дата 


ПО Ч.Измерение1 = Ч1.Измерение1
И Ч.Дата < Ч1.Дата 
И РАЗНОСТЬДАТ(Ч.Дата, Ч1.Дата, ДЕНЬ) = 2


или я ХЗ что за условие на доп. отбор... так и не признался
15. m-serg74 46 17.06.14 00:47 Сейчас в теме
(13) igormiro, кстати в (6) кто то говорил что
Получишь одну запись P1 02.06.2014 19.06.2014 это не правильно.
17. mkalimulin 1148 17.06.14 02:48 Сейчас в теме
(1) igormiro,

ВЫБРАТЬ Т1.Период,Т2.Период
  ПОМЕСТИТЬ КОНЦЫ 
  ИЗ РегистрСведений.Тест как Т1
  ЛЕВОЕ СОЕДИНЕНИЕ
  РегистрСведений.Тест как Т2
  ПО Т2.Период=ДОБАВИТЬКДАТЕ(Т1.Период,День,1)
  ГДЕ Т2.Период ЕСТЬ NULL;
  
  ВЫБРАТЬ
   Т3.Период как ТКонец,
   ЕСТЬNULL(МАКСИМУМ(Т4.Период),ДАТАВРЕМЯ(1,1,1)) как ПКонец
  ПОМЕСТИТЬ  КОНЦЫ2
  ИЗ КОНЦЫ как Т3
  ЛЕВОЕ СОЕДИНЕНИЕ 
  КОНЦЫ как Т4
  ПО Т4.Период<Т3.Период
  СГРУППИРОВАТЬ ПО Т3.Период;
  
  ВЫБРАТЬ 
    МИНИМУМ(Т6.Период) как днач,
    Т5.ТКонец как дкон
  ИЗ КОНЦЫ2 как Т5
  СОЕДИНЕНИЕ 
  РегистрСведений.Тест как Т6
  ПО Т6.Период<=Т5.ТКонец
  И Т6.Период>Т5.ПКонец
  СГРУППИРОВАТЬ ПО Т5.Тконец
  УПОРЯДОЧИТЬ ПО 1
Показать
4. F1215 17.06.14 00:21 Сейчас в теме
мало исходных данных и больше вопросов
5. m-serg74 46 17.06.14 00:22 Сейчас в теме
6. igormiro 714 17.06.14 00:23 Сейчас в теме
Получишь одну запись P1 02.06.2014 19.06.2014 это не правильно.
7. m-serg74 46 17.06.14 00:24 Сейчас в теме
(6) igormiro, это ты кому писал?
8. igormiro 714 17.06.14 00:27 Сейчас в теме
Задача не простая.
Условие соединения это найти интервалы в которых условие даты n=n+1
P1 02.06.2014 04.06.2014
P1 10.06.2014 12.06.2014
P1 17.06.2014 19.06.2014
9. m-serg74 46 17.06.14 00:29 Сейчас в теме
10. m-serg74 46 17.06.14 00:30 Сейчас в теме
(8) igormiro,
почему P1 02.06.2014 04.06.2014
а не P1 02.06.2014 10.06.2014
или P1 03.06.2014 10.06.2014
11. igormiro 714 17.06.14 00:37 Сейчас в теме
P1 02.06.2014
P1 03.06.2014
P1 04.06.2014
Вот один интервал нужно чтобы было P1 02.06.2014 04.06.2014

P1 10.06.2014
P1 11.06.2014
P1 12.06.2014
Вот второй интервал следовательно P1 10.06.2014 12.06.2014

и трейтий

P1 17.06.2014
P1 18.06.2014
P1 19.06.2014
трейтий P1 17.06.2014 19.06.2014
Данные отличаються на 1
12. m-serg74 46 17.06.14 00:41 Сейчас в теме
(11) igormiro, т.е. разница между датами > 1 дня? программирование не понимает слов
Данные отличаються на 1

к тому же
P1 17.06.2014 19.06.2014
данные отличаются на ДВА, не?
16. m-serg74 46 17.06.14 00:53 Сейчас в теме
Для того чтобы решить задачу нужно понять какое условие, не на приведенные конкретные данные + "должно получиться так", а универсальное условие для любого набора данных
18. spezc 782 17.06.14 08:09 Сейчас в теме
ВЫБРАТЬ
	ДАТАВРЕМЯ(2014, 6, 2) КАК Дата
ПОМЕСТИТЬ ТаблицаРегистра

ОБЪЕДИНИТЬ ВСЕ

ВЫБРАТЬ
	ДАТАВРЕМЯ(2014, 6, 3)

ОБЪЕДИНИТЬ ВСЕ

ВЫБРАТЬ
	ДАТАВРЕМЯ(2014, 6, 4)

ОБЪЕДИНИТЬ ВСЕ

ВЫБРАТЬ
	ДАТАВРЕМЯ(2014, 6, 10)

ОБЪЕДИНИТЬ ВСЕ

ВЫБРАТЬ
	ДАТАВРЕМЯ(2014, 6, 11)

ОБЪЕДИНИТЬ ВСЕ

ВЫБРАТЬ
	ДАТАВРЕМЯ(2014, 6, 12)

ОБЪЕДИНИТЬ ВСЕ

ВЫБРАТЬ
	ДАТАВРЕМЯ(2014, 6, 17)

ОБЪЕДИНИТЬ ВСЕ

ВЫБРАТЬ
	ДАТАВРЕМЯ(2014, 6, 18)

ОБЪЕДИНИТЬ ВСЕ

ВЫБРАТЬ
	ДАТАВРЕМЯ(2014, 6, 19)
;

////////////////////////////////////////////////////////////­////////////////////
ВЫБРАТЬ
	ТаблицаРегистра.Дата КАК ДатаНачала,
	ТаблицаРегистраДляСоединения.Дата КАК ДатаОкончания
ИЗ
	ТаблицаРегистра КАК ТаблицаРегистра
		ЛЕВОЕ СОЕДИНЕНИЕ ТаблицаРегистра КАК ТаблицаРегистраДляСоединения
		ПО (ДОБАВИТЬКДАТЕ(ТаблицаРегистра.Дата, ДЕНЬ, 2) = ТаблицаРегистраДляСоединения.Дата)
ГДЕ
	НЕ ТаблицаРегистраДляСоединения.Дата ЕСТЬ NULL 
Показать
19. adva 45 17.06.14 08:41 Сейчас в теме
Наверное так:

ВЫБРАТЬ
	1 КАК Дата
ПОМЕСТИТЬ Даты

ОБЪЕДИНИТЬ ВСЕ

ВЫБРАТЬ
	2

ОБЪЕДИНИТЬ ВСЕ

ВЫБРАТЬ
	3

ОБЪЕДИНИТЬ ВСЕ

ВЫБРАТЬ
	5

ОБЪЕДИНИТЬ ВСЕ

ВЫБРАТЬ
	6
;

////////////////////////////////////////////////////////////­////////////////////
ВЫБРАТЬ
	Даты.Дата
ПОМЕСТИТЬ ПервыеДатыИнтервалов
ИЗ
	Даты КАК Даты
		ЛЕВОЕ СОЕДИНЕНИЕ Даты КАК ДатыДо
		ПО (ДатыДо.Дата = Даты.Дата - 1)
ГДЕ
	ДатыДо.Дата ЕСТЬ NULL 
;

////////////////////////////////////////////////////////////­////////////////////
ВЫБРАТЬ
	Даты.Дата
ПОМЕСТИТЬ ПоследниеДатыИнтервалов
ИЗ
	Даты КАК Даты
		ЛЕВОЕ СОЕДИНЕНИЕ Даты КАК ДатыПосле
		ПО (Даты.Дата + 1 = ДатыПосле.Дата)
ГДЕ
	ДатыПосле.Дата ЕСТЬ NULL 
;

////////////////////////////////////////////////////////////­////////////////////
ВЫБРАТЬ
	ПервыеДатыИнтервалов.Дата КАК ДатаНач,
	МИНИМУМ(ПоследниеДатыИнтервалов.Дата) КАК ДатаКон
ИЗ
	ПервыеДатыИнтервалов КАК ПервыеДатыИнтервалов
		ВНУТРЕННЕЕ СОЕДИНЕНИЕ ПоследниеДатыИнтервалов КАК ПоследниеДатыИнтервалов
		ПО ПервыеДатыИнтервалов.Дата <= ПоследниеДатыИнтервалов.Дата

СГРУППИРОВАТЬ ПО
	ПервыеДатыИнтервалов.Дата
Показать


Не стал измерения приводить, смысл от этого не меняется
21. adva 45 17.06.14 08:44 Сейчас в теме
Решение в (19), думаю числа заменить датами и добавить измерение не составит труда
22. adva 45 17.06.14 08:49 Сейчас в теме
В (19) надо заменить в последнем запросе условие на <= , чтобы 1 день учитывался
28. igormiro 714 17.06.14 10:22 Сейчас в теме
(19) adva,

Правильное решение! Спасибо!
Всем большое спасибо Если есть оптимальные методы то пишите!
Вот окончательный текст запроса

ВЫБРАТЬ
Вз.Дата,
Вз.Измерение
ПОМЕСТИТЬ ВТДаты
ИЗ
(ВЫБРАТЬ
ДАТАВРЕМЯ(2014, 6, 1, 0, 0, 0) КАК Дата,
ВЫРАЗИТЬ("Иванов" КАК СТРОКА(10)) КАК Измерение

ОБЪЕДИНИТЬ ВСЕ

ВЫБРАТЬ
ДАТАВРЕМЯ(2014, 6, 2, 0, 0, 0),
ВЫРАЗИТЬ("Иванов" КАК СТРОКА(10))

ОБЪЕДИНИТЬ ВСЕ

ВЫБРАТЬ
ДАТАВРЕМЯ(2014, 6, 5, 0, 0, 0),
ВЫРАЗИТЬ("Иванов" КАК СТРОКА(10))

ОБЪЕДИНИТЬ ВСЕ

ВЫБРАТЬ
ДАТАВРЕМЯ(2014, 6, 6, 0, 0, 0),
ВЫРАЗИТЬ("Иванов" КАК СТРОКА(10))

ОБЪЕДИНИТЬ ВСЕ

ВЫБРАТЬ
ДАТАВРЕМЯ(2014, 6, 7, 0, 0, 0),
ВЫРАЗИТЬ("Иванов" КАК СТРОКА(10))

ОБЪЕДИНИТЬ ВСЕ

ВЫБРАТЬ
ДАТАВРЕМЯ(2014, 6, 8, 0, 0, 0),
ВЫРАЗИТЬ("Иванов" КАК СТРОКА(10))

ОБЪЕДИНИТЬ ВСЕ

ВЫБРАТЬ
ДАТАВРЕМЯ(2014, 6, 22, 0, 0, 0),
ВЫРАЗИТЬ("Иванов" КАК СТРОКА(10))) КАК Вз
;

////////////////////////////////////////////////////////////­////////////////////
ВЫБРАТЬ
Даты.Дата
ПОМЕСТИТЬ ПервыеДатыИнтервалов
ИЗ
ВТДаты КАК Даты
ЛЕВОЕ СОЕДИНЕНИЕ ВТДаты КАК ДатыДо
ПО (ДатыДо.Дата = ДОБАВИТЬКДАТЕ(Даты.Дата, ДЕНЬ, -1))
ГДЕ
ДатыДо.Дата ЕСТЬ NULL
;

////////////////////////////////////////////////////////////­////////////////////
ВЫБРАТЬ
Даты.Дата
ПОМЕСТИТЬ ПоследниеДатыИнтервалов
ИЗ
ВТДаты КАК Даты
ЛЕВОЕ СОЕДИНЕНИЕ ВТДаты КАК ДатыПосле
ПО (ДатыПосле.Дата = ДОБАВИТЬКДАТЕ(Даты.Дата, ДЕНЬ, 1))
ГДЕ
ДатыПосле.Дата ЕСТЬ NULL
;

////////////////////////////////////////////////////////////­////////////////////
ВЫБРАТЬ
ПервыеДатыИнтервалов.Дата КАК ДатаНач,
МИНИМУМ(ПоследниеДатыИнтервалов.Дата) КАК ДатаКон
ИЗ
ПервыеДатыИнтервалов КАК ПервыеДатыИнтервалов
ВНУТРЕННЕЕ СОЕДИНЕНИЕ ПоследниеДатыИнтервалов КАК ПоследниеДатыИнтервалов
ПО ПервыеДатыИнтервалов.Дата <= ПоследниеДатыИнтервалов.Дата

СГРУППИРОВАТЬ ПО
ПервыеДатыИнтервалов.Дата
29. miniogn 23 17.06.14 10:26 Сейчас в теме
(28) В (27) Оптимальнее или нет, но короче
31. adva 45 17.06.14 11:04 Сейчас в теме
(28) спасибо, не совсем правильно, во всех условиях соединения надо добавить условие на равенство измерения, иначе в кучу смешаются разные измерения
20. igormiro 714 17.06.14 08:43 Сейчас в теме
Пишу ещё раз условие есть регистр сведений периодичностью месяц назывееться больничные, там 2 измерения сотрудник и дата болезни.
Пользователь проставляет даты больничных пример
Иванов болел 1.06 , 2.06, ,11.06,12.06, 29.06 .
Нужно найти интервалы болезни
ДЛЯ Иванова:

Иванов 1.06 - 2.06,
10.06-12.06
29.06-29.06
23. spezc 782 17.06.14 08:57 Сейчас в теме
(20) igormiro, скопируй сюда данные твоего регистра, или проще всего приложи скрин. а то на самом деле не совсем понятно, какие данные имеются и что все-таки хочешь получить.
непонятно как из "1.06 , 2.06, ,11.06,12.06, 29.06" получается:
1.06 - 2.06,
10.06-12.06
29.06-29.06
24. miniogn 23 17.06.14 09:16 Сейчас в теме
Вот порешал из спортивного интереса

ВЫБРАТЬ
	"P1" КАК Измерение1,
	ДАТАВРЕМЯ(2014, 6, 2) КАК Дата
ПОМЕСТИТЬ ВТДаты
;
ВЫБРАТЬ
	ЕСТЬNULL(ВТДаты.Измерение1, ВТДаты1.Измерение1) КАК Измерение1,
	ВТДаты.Дата КАК Дата,
	ВТДаты1.Дата КАК СледующаяДата
ПОМЕСТИТЬ ВТТаблица
ИЗ
	ВТДаты КАК ВТДаты
		ПОЛНОЕ СОЕДИНЕНИЕ ВТДаты КАК ВТДаты1
		ПО ВТДаты.Измерение1 = ВТДаты1.Измерение1
			И (ДОБАВИТЬКДАТЕ(ВТДаты.Дата, ДЕНЬ, 1) = ВТДаты1.Дата)
ГДЕ
	(ВТДаты.Дата ЕСТЬ NULL ИЛИ ВТДаты1.Дата ЕСТЬ NULL)
;

////////////////////////////////////////////////////////////­////////////////////
ВЫБРАТЬ РАЗЛИЧНЫЕ
	ВТДаты.Измерение1,
	МАКСИМУМ(ВТДатыС.СледующаяДата) КАК ДатаС,
	МИНИМУМ(ВТДатыПо.Дата) КАК ДатаПо
ИЗ
	ВТДаты КАК ВТДаты
		ЛЕВОЕ СОЕДИНЕНИЕ ВТТаблица КАК ВТДатыС
		ПО ВТДаты.Измерение1 = ВТДатыС.Измерение1
			И ВТДаты.Дата >= ВТДатыС.СледующаяДата
		ЛЕВОЕ СОЕДИНЕНИЕ ВТТаблица КАК ВТДатыПо
		ПО ВТДаты.Измерение1 = ВТДатыПо.Измерение1
			И ВТДаты.Дата <= ВТДатыПо.Дата

СГРУППИРОВАТЬ ПО
	ВТДаты.Измерение1,
	ВТДаты.Дата
Показать
25. spezc 782 17.06.14 09:19 Сейчас в теме
(24) miniogn, а какую задачу решал то, если не секрет?
26. miniogn 23 17.06.14 09:29 Сейчас в теме
(25) spezc, Получить непрерывные диапазоны
27. miniogn 23 17.06.14 09:30 Сейчас в теме
Вот так еще проще

ВЫБРАТЬ
	ЕСТЬNULL(ВТДаты.Измерение1, ВТДаты1.Измерение1) КАК Измерение1,
	ВТДаты.Дата КАК Дата,
	ВТДаты1.Дата КАК СледующаяДата
ПОМЕСТИТЬ ВТТаблица
ИЗ
	ВТДаты КАК ВТДаты
		ПОЛНОЕ СОЕДИНЕНИЕ ВТДаты КАК ВТДаты1
		ПО ВТДаты.Измерение1 = ВТДаты1.Измерение1
			И (ДОБАВИТЬКДАТЕ(ВТДаты.Дата, ДЕНЬ, 1) = ВТДаты1.Дата)
ГДЕ
	(ВТДаты.Дата ЕСТЬ NULL 
			ИЛИ ВТДаты1.Дата ЕСТЬ NULL )
;

////////////////////////////////////////////////////////////­////////////////////
ВЫБРАТЬ
	ВТДатыС.Измерение1,
	ВТДатыС.СледующаяДата КАК ДатаС,
	МИНИМУМ(ВТДатыПо.Дата) КАК Дата
ИЗ
	ВТТаблица КАК ВТДатыС
		ВНУТРЕННЕЕ СОЕДИНЕНИЕ ВТТаблица КАК ВТДатыПо
		ПО ВТДатыС.Измерение1 = ВТДатыПо.Измерение1
			И ВТДатыС.СледующаяДата <= ВТДатыПо.Дата

СГРУППИРОВАТЬ ПО
	ВТДатыС.Измерение1,
	ВТДатыС.СледующаяДата
Показать
30. igormiro 714 17.06.14 10:31 Сейчас в теме
(27) miniogn, Тоже правильное решение!!!
Вознаграждение отдал adva, так как он решил раньше.
Все равно большое спасибо!!!
32. ildarovich 7850 19.06.14 21:03 Сейчас в теме
(27)(28) Вот еще проще
ВЫБРАТЬ
Даты.Дата,
КОЛИЧЕСТВО(РАЗЛИЧНЫЕ ДатыДо.Дата) КАК Номер
ПОМЕСТИТЬ НомераДат
ИЗ
ВТДаты КАК Даты
ВНУТРЕННЕЕ СОЕДИНЕНИЕ ВТДаты КАК ДатыДо
ПО (ДатыДо.Дата <= Даты.Дата)

СГРУППИРОВАТЬ ПО
Даты.Дата
;

////////////////////////////////////////////////////////////­////////////////////
ВЫБРАТЬ
МИНИМУМ(НомераДат.Дата) КАК ДатаНач,
МАКСИМУМ(НомераДат.Дата) КАК ДатаКон
ИЗ
НомераДат КАК НомераДат

СГРУППИРОВАТЬ ПО
ДОБАВИТЬКДАТЕ(НомераДат.Дата, ДЕНЬ, -НомераДат.Номер)
Показать
BigB; Xershi; mai_k; user802000; +4 Ответить
34. miniogn 23 20.06.14 09:16 Сейчас в теме
(32) ildarovich, Сдается мне, что сервер повесится на подсчете количества дат.
35. ildarovich 7850 20.06.14 10:27 Сейчас в теме
(34) miniogn, задача связывания начал отрезков с их концами (решаемая в вашем подходе в последнем запросе) - это примерно такая же по вычислительной сложности задача, только она будет зависеть от квадрата числа отрезков, а при подсчете количества дат - от квадрата количества дат.
Также кажется, что для соединения по условию
(ДатыДо.Дата = ДОБАВИТЬКДАТЕ(Даты.Дата, ДЕНЬ, -1))
придется для каждой даты просканировать все другие даты. Это тоже задача, имеющая квадратичную трудоемкость. Правда, последнюю трудность можно преодолеть, используя вместо соединения группировку.
А вообще я знаю как решить эту задачу за линейное время, используя метод типа "баттерфляй", но здесь речь не шла о высочайшей скорости и супербольших объемах данных, поэтому я и предложил суперкомпактный метод.
36. miniogn 23 20.06.14 10:34 Сейчас в теме
(35) ildarovich, Вы наверное правы
38. Xershi 1474 28.01.20 21:22 Сейчас в теме
(32)
ВЫБРАТЬ
	ТаблицаДат.Дата КАК Дата,
	ТаблицаДат.ВидДеятельности КАК ВидДеятельности
ПОМЕСТИТЬ ВТДаты
ИЗ
	&ТаблицаДат КАК ТаблицаДат
;

////////////////////////////////////////////////////////////­////////////////////
ВЫБРАТЬ
	Даты.Дата КАК Дата,
	КОЛИЧЕСТВО(РАЗЛИЧНЫЕ ДатыДо.Дата) КАК Номер,
	Даты.ВидДеятельности КАК ВидДеятельности
ПОМЕСТИТЬ НомераДат
ИЗ
	ВТДаты КАК Даты
		ВНУТРЕННЕЕ СОЕДИНЕНИЕ ВТДаты КАК ДатыДо
		ПО (ДатыДо.Дата <= Даты.Дата)
			И Даты.ВидДеятельности = ДатыДо.ВидДеятельности

СГРУППИРОВАТЬ ПО
	Даты.Дата,
	Даты.ВидДеятельности
;

////////////////////////////////////////////////////////////­////////////////////
ВЫБРАТЬ
	МИНИМУМ(НомераДат.Дата) КАК ДатаНач,
	МАКСИМУМ(НомераДат.Дата) КАК ДатаКон,
	НомераДат.ВидДеятельности КАК ВидДеятельности
ИЗ
	НомераДат КАК НомераДат

СГРУППИРОВАТЬ ПО
	ДОБАВИТЬКДАТЕ(НомераДат.Дата, ДЕНЬ, -НомераДат.Номер),
	НомераДат.ВидДеятельности
Показать

Теперь решал такую же задачу, только кроме интервала дат, нужно было еще добавить аналитику.
33. ildarovich 7850 19.06.14 21:12 Сейчас в теме
37. Xershi 1474 23.03.19 22:49 Сейчас в теме
(33) решал похожую задачу. Но там был период в виде начала и конца.
Никак не мог составить условие.
В итоге понял в чем суть и получилось вот такое:
ВЫБРАТЬ
	НахождениеВГеозоне.Клиент КАК Клиент,
	НахождениеВГеозоне.НачалоПериода КАК НачалоПериода,
	НахождениеВГеозоне.КонецПериода КАК КонецПериода,
	НахождениеВГеозоне.Геозона КАК Геозона
ПОМЕСТИТЬ Дано
ИЗ
	РегистрСведений.НахождениеВГеозоне КАК НахождениеВГеозоне
;

////////////////////////////////////////////////////////////­////////////////////
ВЫБРАТЬ
	Дано.Клиент КАК Клиент,
	Дано.НачалоПериода КАК НачалоПериода,
	Дано.КонецПериода КАК КонецПериода,
	Дано.Геозона КАК Геозона,
	СУММА(РАЗНОСТЬДАТ(ДатыДо.НачалоПериода, ДатыДо.КонецПериода, СЕКУНДА)) КАК Интеграл
ПОМЕСТИТЬ ДаноПлюс
ИЗ
	Дано КАК Дано
		ВНУТРЕННЕЕ СОЕДИНЕНИЕ Дано КАК ДатыДо
		ПО (ДатыДо.НачалоПериода <= Дано.НачалоПериода)
			И (ДатыДо.Клиент = Дано.Клиент)
			И (ДатыДо.Геозона = Дано.Геозона)

СГРУППИРОВАТЬ ПО
	Дано.НачалоПериода,
	Дано.КонецПериода,
	Дано.Клиент,
	Дано.Геозона
;

////////////////////////////////////////////////////////////­////////////////////
ВЫБРАТЬ
	МИНИМУМ(Дано.НачалоПериода) КАК НачалоПериода,
	МАКСИМУМ(Дано.КонецПериода) КАК КонецПериода,
	Дано.Клиент КАК Клиент,
	Дано.Геозона КАК Геозона
ИЗ
	ДаноПлюс КАК Дано

СГРУППИРОВАТЬ ПО
	ДОБАВИТЬКДАТЕ(Дано.КонецПериода, СЕКУНДА, -Дано.Интеграл),
	Дано.Клиент,
	Дано.Геозона
Показать

Важный момент в определении интервалов "ДатыДо.НачалоПериода <= Дано.НачалоПериода" и "ДОБАВИТЬКДАТЕ(Дано.КонецПериода, СЕКУНДА, -Дано.Интеграл)" в таком ключе интервалы становятся как нужно!
39. Hobbit_Jedi 07.02.20 16:49 Сейчас в теме
(37)
решал похожую задачу

Если период полностью лежит внутри другого периода, то на выходе они двумя отдельными периодами получаются :(
Так что не совсем работает данный метод :(

Пример входных данных для воспроизведения:

ВЫБРАТЬ
    "Клиент1" КАК Клиент,
    ДАТАВРЕМЯ(2020,01,01,10,0,0) КАК НачалоПериода,
    ДАТАВРЕМЯ(2020,01,10,15,0,0) КАК КонецПериода,
    "Гео1" КАК Геозона
ПОМЕСТИТЬ Дано

ОБЪЕДИНИТЬ ВСЕ

ВЫБРАТЬ
    "Клиент1" КАК Клиент,
    ДАТАВРЕМЯ(2020,01,01,12,0,0) КАК НачалоПериода,
    ДАТАВРЕМЯ(2020,01,05,00,0,0) КАК КонецПериода,
    "Гео1" КАК Геозона

ОБЪЕДИНИТЬ ВСЕ

ВЫБРАТЬ
    "Клиент1" КАК Клиент,
    ДАТАВРЕМЯ(2020,02,01,10,0,0) КАК НачалоПериода,
    ДАТАВРЕМЯ(2020,02,03,10,0,0) КАК КонецПериода,
    "Гео1" КАК Геозона

ОБЪЕДИНИТЬ ВСЕ

ВЫБРАТЬ
    "Клиент1" КАК Клиент,
    ДАТАВРЕМЯ(2020,02,03,10,0,0) КАК НачалоПериода,
    ДАТАВРЕМЯ(2020,02,14,18,0,0) КАК КонецПериода,
    "Гео1" КАК Геозона

ОБЪЕДИНИТЬ ВСЕ

ВЫБРАТЬ
    "Клиент1" КАК Клиент,
    ДАТАВРЕМЯ(2020,02,04,11,0,0) КАК НачалоПериода,
    ДАТАВРЕМЯ(2020,02,04,20,0,0) КАК КонецПериода,
    "Гео1" КАК Геозона
;
Показать


Должно получиться два периода:
01.01.2020 10:00 - 10.01.2020 15:00
01.02.2020 10:00 - 14.02.2020 18:00

А оно, кроме этих двух периодов, еще два полностью поглощенных периода выводит:
01.01.2020 12:00 - 05.01.2020 00:00
04.02 2020 11:00 - 04.02.2020 20:00
40. Xershi 1474 07.02.20 16:55 Сейчас в теме
(39) возможно вы правы. Но проверить уже не смогу, если будет такая задача сверимся!
41. пользователь 07.02.20 18:32
Сообщение было скрыто модератором.
...
42. Hobbit_Jedi 07.02.20 18:35 Сейчас в теме
(37)

Дополнил Ваше решение, чтобы из результирующей таблицы убирались периоды, которые полностью поглощены другими периодами.

ВЫБРАТЬ
    "Клиент1" КАК Клиент,
    "Гео1" КАК Геозона,
    ДАТАВРЕМЯ(2020,01,01,10,0,0) КАК НачалоПериода,
    ДАТАВРЕМЯ(2020,01,10,15,0,0) КАК КонецПериода
ПОМЕСТИТЬ Дано

ОБЪЕДИНИТЬ ВСЕ

ВЫБРАТЬ
    "Клиент1" КАК Клиент,
    "Гео1" КАК Геозона,
    ДАТАВРЕМЯ(2020,01,01,12,0,0) КАК НачалоПериода,
    ДАТАВРЕМЯ(2020,01,05,00,0,0) КАК КонецПериода

ОБЪЕДИНИТЬ ВСЕ

ВЫБРАТЬ
    "Клиент1" КАК Клиент,
    "Гео1" КАК Геозона,
    ДАТАВРЕМЯ(2020,02,01,10,0,0) КАК НачалоПериода,
    ДАТАВРЕМЯ(2020,02,03,10,0,0) КАК КонецПериода

ОБЪЕДИНИТЬ ВСЕ

ВЫБРАТЬ
    "Клиент1" КАК Клиент,
    "Гео1" КАК Геозона,
    ДАТАВРЕМЯ(2020,02,03,10,0,0) КАК НачалоПериода,
    ДАТАВРЕМЯ(2020,02,14,18,0,0) КАК КонецПериода

ОБЪЕДИНИТЬ ВСЕ

ВЫБРАТЬ
    "Клиент1" КАК Клиент,
    "Гео1" КАК Геозона,
    ДАТАВРЕМЯ(2020,02,04,11,0,0) КАК НачалоПериода,
    ДАТАВРЕМЯ(2020,02,04,20,0,0) КАК КонецПериода
;

////////////////////////////////////////////////////////////­////////////////////
ВЫБРАТЬ
    Дано.Клиент КАК Клиент,
    Дано.НачалоПериода КАК НачалоПериода,
    Дано.КонецПериода КАК КонецПериода,
    Дано.Геозона КАК Геозона,
    СУММА(РАЗНОСТЬДАТ(ДатыДо.НачалоПериода, ДатыДо.КонецПериода, СЕКУНДА)) КАК Интеграл
ПОМЕСТИТЬ ДаноПлюс
ИЗ
    Дано КАК Дано
        ВНУТРЕННЕЕ СОЕДИНЕНИЕ Дано КАК ДатыДо
        ПО (ДатыДо.НачалоПериода <= Дано.НачалоПериода)
            И (ДатыДо.Клиент = Дано.Клиент)
            И (ДатыДо.Геозона = Дано.Геозона)

СГРУППИРОВАТЬ ПО
    Дано.НачалоПериода,
    Дано.КонецПериода,
    Дано.Клиент,
    Дано.Геозона
;

////////////////////////////////////////////////////////////­////////////////////
ВЫБРАТЬ
    МИНИМУМ(Дано.НачалоПериода) КАК НачалоПериода,
    МАКСИМУМ(Дано.КонецПериода) КАК КонецПериода,
    Дано.Клиент КАК Клиент,
    Дано.Геозона КАК Геозона
ПОМЕСТИТЬ вт_РезультатСПоглощенными
ИЗ
    ДаноПлюс КАК Дано

СГРУППИРОВАТЬ ПО
    ДОБАВИТЬКДАТЕ(Дано.КонецПериода, СЕКУНДА, -Дано.Интеграл),
    Дано.Клиент,
    Дано.Геозона
;
///////////////////////////////////////////////
// вт_Поглощенные
ВЫБРАТЬ
	вт_РезультатСПоглощенными.Клиент        КАК Клиент,
	вт_РезультатСПоглощенными.Геозона       КАК Геозона,
	вт_РезультатСПоглощенными.НачалоПериода КАК НачалоПериода,
	вт_РезультатСПоглощенными.КонецПериода  КАК КонецПериода
ПОМЕСТИТЬ вт_Поглощенные
ИЗ вт_РезультатСПоглощенными КАК вт_РезультатСПоглощенными
	ВНУТРЕННЕЕ СОЕДИНЕНИЕ вт_РезультатСПоглощенными КАК Поглотители
		ПО вт_РезультатСПоглощенными.Клиент = Поглотители.Клиент
			И вт_РезультатСПоглощенными.Геозона = Поглотители.Геозона
			И вт_РезультатСПоглощенными.НачалоПериода >= Поглотители.НачалоПериода
			И вт_РезультатСПоглощенными.КонецПериода <= Поглотители.КонецПериода
			И вт_РезультатСПоглощенными.НачалоПериода <> Поглотители.НачалоПериода
			И вт_РезультатСПоглощенными.КонецПериода <> Поглотители.КонецПериода
;
///////////////////////////////////////////////
// Запрос-результат
ВЫБРАТЬ
	вт_РезультатСПоглощенными.Клиент        КАК Клиент,
	вт_РезультатСПоглощенными.Геозона        КАК Геозона,
	вт_РезультатСПоглощенными.НачалоПериода КАК НачалоПериода,
	вт_РезультатСПоглощенными.КонецПериода  КАК КонецПериода
ИЗ вт_РезультатСПоглощенными КАК вт_РезультатСПоглощенными
	ЛЕВОЕ СОЕДИНЕНИЕ вт_Поглощенные КАК вт_Поглощенные
		ПО вт_РезультатСПоглощенными.Клиент = вт_Поглощенные.Клиент
			И вт_РезультатСПоглощенными.Геозона = вт_Поглощенные.Геозона
			И вт_РезультатСПоглощенными.НачалоПериода = вт_Поглощенные.НачалоПериода
			И вт_РезультатСПоглощенными.КонецПериода = вт_Поглощенные.КонецПериода
ГДЕ
	вт_Поглощенные.Клиент ЕСТЬ NULL
;
Показать
43. Hobbit_Jedi 07.02.20 19:53 Сейчас в теме
(42)
Дополнил Ваше решение


Не. Такое решение тоже не совсем работает.
Если есть период, который пересекает два других периода, соприкасающихся между собой, то запрос не видит поглощение такого периода "объединением соприкасающихся периодов".

Например периоды:
1 - 3 февраля
2 - 4 февраля
3 - 10 февраля

А также, не видит возможность объединить периоды в более сложной ситуации, когда есть три периода, попарно пересекающихся, то запрос не объединяет их в один:
1 - 3 февраля
2 - 5 февраля
4 - 10 февраля

В-общем, правильное решение задачи такое.
Изначальную таблицу периодов помещаем в Дано (см. примеры в предыдущих сообщениях).
А затем в цикле гоняем запросы, пока в последнем запросе количество строк уменьшаться не перестанет (значит объединили все, что можно было объединить).

////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ
    Дано.Клиент КАК Клиент,
    Дано.Геозона КАК Геозона,
    Дано.НачалоПериода КАК НачалоПериода,
    Дано.КонецПериода КАК КонецПериода,
    СУММА(
    		РАЗНОСТЬДАТ	(
    						ДатыДо.НачалоПериода,
    						ВЫБОР
    							КОГДА ДатыДо.КонецПериода <= Дано.НачалоПериода
    								ИЛИ (ДатыДо.НачалоПериода = Дано.НачалоПериода И ДатыДо.КонецПериода = Дано.КонецПериода)
    							ТОГДА
    								ДатыДо.КонецПериода
    							ИНАЧЕ
    								Дано.НачалоПериода
    						КОНЕЦ,
    						СЕКУНДА
    					)
    ) КАК Интеграл
ПОМЕСТИТЬ ДаноПлюс
ИЗ
    Дано КАК Дано
        ВНУТРЕННЕЕ СОЕДИНЕНИЕ Дано КАК ДатыДо
        ПО (ДатыДо.НачалоПериода <= Дано.НачалоПериода)
            И (ДатыДо.Клиент = Дано.Клиент)
            И (ДатыДо.Геозона = Дано.Геозона)

СГРУППИРОВАТЬ ПО
    Дано.НачалоПериода,
    Дано.КонецПериода,
    Дано.Клиент,
    Дано.Геозона
;
////////////////////////////////////////////////////////////­////////////////////
УНИЧТОЖИТЬ Дано
;
////////////////////////////////////////////////////////////­////////////////////
ВЫБРАТЬ
    Дано.Клиент КАК Клиент,
    Дано.Геозона КАК Геозона,
    МИНИМУМ(Дано.НачалоПериода) КАК НачалоПериода,
    МАКСИМУМ(Дано.КонецПериода) КАК КонецПериода
ПОМЕСТИТЬ Дано
ИЗ
    ДаноПлюс КАК Дано

СГРУППИРОВАТЬ ПО
    Дано.Клиент,
    Дано.Геозона,
    ДОБАВИТЬКДАТЕ(Дано.КонецПериода, СЕКУНДА, -Дано.Интеграл)
;
Показать


Обратите внимание на ВЫБОР в первом запросе. Он позволяет объединять пересекающиеся (а не соприкасающиеся) периоды. В том числе и поглощенные периоды убирает.
Оставьте свое сообщение
Вакансии
1С аналитик
Москва
зарплата от 210 000 руб.
Полный день

Руководитель направления 1С
Москва
зарплата от 350 000 руб.
Полный день

1С Программист
Москва
зарплата от 180 000 руб.
Полный день

Программист 1С
Москва
зарплата от 180 000 руб. до 220 000 руб.
Полный день

Аналитик 1С / Бизнес-аналитик
Нижний Новгород
зарплата от 100 000 руб. до 250 000 руб.
Временный (на проект)