Добрый день!

Есть НЕпериодический регистр сведений с измерением "НомерСтроки" типа "Число" и ресурсом "Флаг" типа "Булево".

Флаг, как правило, имеет значение "Ложь", но отдельные записи имеют значение "Истина" - как одиночные, так и несколько подряд.

Требуется получить интервалы номеров строк, где флаг имеет значение "Истина". Например, если флаг имеет значение "Истина" в строках №№ 101, 201, 202, 203 первый интервал должен быть 101-101, а второй 201-203.

Можно ли как-то извернуться через запрос?

Можно, конечно, отобрать через "ГДЕ" только истинные флаги, отсортировать по номеру строки и получить интервалы руками, но так не интересно.
---
Ну держи. У меня это сейчас работает. Правда нельзя создать регистр с измерением "НомерСтроки", так что он у меня называется "НомерСтрокиРегистра". И еще, автор признайся, это задача с собеседования? Потому что я ума не приложу, где в реальной практике это может пригодиться. Такие абстрактные задачи обычно с собеседований тащат

```1c
    ВЫБРАТЬ
    РегистрНомеров.НомерСтрокиРегистра КАК НомерСтрокиРегистра,
    РегистрНомеров.Флаг КАК Флаг
    ПОМЕСТИТЬ ПервичнаяВыборка
    ИЗ
    РегистрСведений.РегистрНомеров КАК РегистрНомеров
    ГДЕ
    РегистрНомеров.Флаг
    ;

    ////////////////////////////////////////////////////////////­////////////////////
    ВЫБРАТЬ
    ПервичнаяВыборка.НомерСтрокиРегистра КАК НомерСтрокиРегистра,
    ЕСТЬNULL(ПервичнаяВыборкаСледующийНомер.Флаг, ЛОЖЬ) КАК ЕстьСледующийНомер,
    ЕСТЬNULL(ПервичнаяВыборкаПредыдущийНомер.Флаг, ЛОЖЬ) КАК ЕстьПредыдущийНомер
    ПОМЕСТИТЬ АнализНомеров
    ИЗ
    ПервичнаяВыборка КАК ПервичнаяВыборка
    ЛЕВОЕ СОЕДИНЕНИЕ ПервичнаяВыборка КАК ПервичнаяВыборкаСледующийНомер
    ПО (ПервичнаяВыборка.НомерСтрокиРегистра = ПервичнаяВыборкаСледующийНомер.НомерСтрокиРегистра + 1)
    ЛЕВОЕ СОЕДИНЕНИЕ ПервичнаяВыборка КАК ПервичнаяВыборкаПредыдущийНомер
    ПО (ПервичнаяВыборка.НомерСтрокиРегистра = ПервичнаяВыборкаПредыдущийНомер.НомерСтрокиРегистра - 1)
    ;

    ////////////////////////////////////////////////////////////­////////////////////
    ВЫБРАТЬ
    АнализНомеров.НомерСтрокиРегистра КАК НомерСтрокиРегистра,
    ВЫБОР
    КОГДА НЕ АнализНомеров.ЕстьСледующийНомер
    И НЕ АнализНомеров.ЕстьПредыдущийНомер
    ТОГДА ЛОЖЬ
    ИНАЧЕ ИСТИНА
    КОНЕЦ КАК ЭтоИнтервал
    ПОМЕСТИТЬ ВсеИнтервалы
    ИЗ
    АнализНомеров КАК АнализНомеров
    ГДЕ
    НЕ(АнализНомеров.ЕстьСледующийНомер
    И АнализНомеров.ЕстьПредыдущийНомер)
    ;

    ////////////////////////////////////////////////////////////­////////////////////
    ВЫБРАТЬ
    ВсеИнтервалы.НомерСтрокиРегистра КАК ПервыйНомерИнтервала,
    ВсеИнтервалы.НомерСтрокиРегистра КАК ВторойНомерИнтервала
    ПОМЕСТИТЬ ОдлиночныеИнтервалы
    ИЗ
    ВсеИнтервалы КАК ВсеИнтервалы
    ГДЕ
    НЕ ВсеИнтервалы.ЭтоИнтервал
    ;

    ////////////////////////////////////////////////////////////­////////////////////
    ВЫБРАТЬ
    ВсеИнтервалы.НомерСтрокиРегистра КАК НомерСтрокиРегистра
    ПОМЕСТИТЬ ДвойныеИнтервалыВСтолбец
    ИЗ
    ВсеИнтервалы КАК ВсеИнтервалы
    ГДЕ
    ВсеИнтервалы.ЭтоИнтервал
    ;

    ////////////////////////////////////////////////////////////­////////////////////
    ВЫБРАТЬ
    ВсеИнтервалы.НомерСтрокиРегистра КАК НомерСтрокиРегистра
    ПОМЕСТИТЬ ДвойныеИнтервалыПервыйНомер
    ИЗ
    ВсеИнтервалы КАК ВсеИнтервалы
    ЛЕВОЕ СОЕДИНЕНИЕ АнализНомеров КАК АнализНомеров
    ПО ВсеИнтервалы.НомерСтрокиРегистра = АнализНомеров.НомерСтрокиРегистра
    ГДЕ
    ВсеИнтервалы.ЭтоИнтервал
    И АнализНомеров.ЕстьПредыдущийНомер
    ;

    ////////////////////////////////////////////////////////////­////////////////////
    ВЫБРАТЬ
    ДвойныеИнтервалыПервыйНомер.НомерСтрокиРегистра КАК ПервыйНомерИнтервала,
    МИНИМУМ(ДвойныеИнтервалыВСтолбец.НомерСтрокиРегистра) КАК ВторойНомерИнтервала
    ПОМЕСТИТЬ ДвойныеИнтервалыВСтроку
    ИЗ
    ДвойныеИнтервалыПервыйНомер КАК ДвойныеИнтервалыПервыйНомер
    ЛЕВОЕ СОЕДИНЕНИЕ ДвойныеИнтервалыВСтолбец КАК ДвойныеИнтервалыВСтолбец
    ПО ДвойныеИнтервалыПервыйНомер.НомерСтрокиРегистра < ДвойныеИнтервалыВСтолбец.НомерСтрокиРегистра

    СГРУППИРОВАТЬ ПО
    ДвойныеИнтервалыПервыйНомер.НомерСтрокиРегистра
    ;

    ////////////////////////////////////////////////////////////­////////////////////
    ВЫБРАТЬ
    ОдлиночныеИнтервалы.ПервыйНомерИнтервала КАК ПервыйНомерИнтервала,
    ОдлиночныеИнтервалы.ВторойНомерИнтервала КАК ВторойНомерИнтервала
    ИЗ
    ОдлиночныеИнтервалы КАК ОдлиночныеИнтервалы

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

    ВЫБРАТЬ
    ДвойныеИнтервалыВСтроку.ПервыйНомерИнтервала,
    ДвойныеИнтервалыВСтроку.ВторойНомерИнтервала
    ИЗ
    ДвойныеИнтервалыВСтроку КАК ДвойныеИнтервалыВСтроку

    УПОРЯДОЧИТЬ ПО
    ПервыйНомерИнтервала
```
---
Можно ли как-то извернуться через запрос?Можно, но зачем? Это однопроходная операция, 1С это сделает предположу быстрее, чем SQL, т.к. SQL будет агрегировать что-то типа треугольной таблицы, ища максимальное количество истин между текущим и предыдущим значением - от еще геморрой.

В запросе это может быть оправдано лишь даже и не знаю когда, т.к. всегда в запрос можно передать таблицу значений с интервалами, полученными в один проход. Там код-то строк пять в цикле.
---
Можно, конечно, отобрать через "ГДЕ" только истинные флаги, отсортировать по номеру строки и получить интервалы руками, но так не интересно.Был у меня одноклассник-медалист, который замену значений двух переменных делал через сложение/вычитание. Типа памяти меньше будет использоваться. Читается такой код очень не очень. Подумайте о тех, кто в дальнейшем будет сопровождать этот код. Вы же там не на всегда...
---
замену значений двух переменных делал через сложение/вычитание

Обычно через XOR делали, про это даже анекдот был.

(29) одноклассник-медалист

Медалисты - это нечто. Помню, принесли мне на вёрстку текст, надо было подвинуть таблицу, а она как-то странно себя ведёт. Оказалось, девочка-медалистка разогнала текст пробелами и обрисовала линиями из векторных рисунков. А таблиц было много, эх и исплевался я с ними тогда!

(29) Вы же там не на всегда

Типун вам на язык!
---
Какие поля нужно получить на выходе?
---
В заголовках итогов:

1) начало интервала, то есть номер строки для первой записи, которая стала первой с Флаг=Истина после последовательности с Флаг=Ложь
2) конец интервала, то есть номер строки, на которой Флаг=Истина закончилось в данном заходе, то есть эта запись либо последняя во всём запросе, либо же после неё идёт запись с Флаг=Ложь

конец интервала=начало интервала, если запись с Флаг=Истина торчит одна среди записей с Флаг=Ложь либо же
конец интервала>начало интервала, если идёт несколько записей с Флаг=Истина подряд.

внутри итогов - ключи + почти все поля, которые в регистре есть.
---
так как у меня нет регистра, я данные беру из собранной тз.
Вам этого не нужно, поэтому просто удалите первый запрос формирующий временную таблицу тмпРегистрСведений и замените вызов
тмпРегистрСведений на ваш регистр.

```1c
    ВЫБРАТЬ
    тз.НомерСтроки КАК НомерСтроки,
    тз.Флаг КАК Флаг,
    "Данные" КАК ПоляДанных
    ПОМЕСТИТЬ тмпРегистрСведений
    ИЗ
    &тз КАК тз
    ;

    ////////////////////////////////////////////////////////////­////////////////////
    ВЫБРАТЬ
    тмпРегистрСведений.НомерСтроки КАК НомерСтроки,
    тмпРегистрСведений.Флаг КАК Флаг
    ПОМЕСТИТЬ тмпВыборкаИнтервалов
    ИЗ
    тмпРегистрСведений КАК тмпРегистрСведений

    ИНДЕКСИРОВАТЬ ПО
    Флаг,
    НомерСтроки
    ;

    ////////////////////////////////////////////////////////////­////////////////////
    ВЫБРАТЬ
    взСтрокиИнтервалов.НомерСтроки КАК НомерСтроки,
    взСтрокиИнтервалов.Флаг КАК Флаг,
    взСтрокиИнтервалов.НомерСтрокиДоИнтервала КАК НомерСтрокиДоИнтервала,
    NULL КАК НачалоИнтервала,
    NULL КАК КонецИнтервала,
    тмпРегистрСведений.ПоляДанных КАК ПоляДанных
    ИЗ
    (ВЫБРАТЬ
    тмпВыборкаА_СтрокиИнтервалов.НомерСтроки КАК НомерСтроки,
    тмпВыборкаА_СтрокиИнтервалов.Флаг КАК Флаг,
    МАКСИМУМ(тмпВыборкаБ_СтрокиДоИнтервала.НомерСтроки) КАК НомерСтрокиДоИнтервала
    ИЗ
    тмпВыборкаИнтервалов КАК тмпВыборкаА_СтрокиИнтервалов
    ЛЕВОЕ СОЕДИНЕНИЕ тмпВыборкаИнтервалов КАК тмпВыборкаБ_СтрокиДоИнтервала
    ПО (тмпВыборкаБ_СтрокиДоИнтервала.Флаг = ЛОЖЬ)
    И тмпВыборкаА_СтрокиИнтервалов.НомерСтроки > тмпВыборкаБ_СтрокиДоИнтервала.НомерСтроки
    ГДЕ
    тмпВыборкаА_СтрокиИнтервалов.Флаг = ИСТИНА

    СГРУППИРОВАТЬ ПО
    тмпВыборкаА_СтрокиИнтервалов.НомерСтроки,
    тмпВыборкаА_СтрокиИнтервалов.Флаг) КАК взСтрокиИнтервалов
    ВНУТРЕННЕЕ СОЕДИНЕНИЕ тмпРегистрСведений КАК тмпРегистрСведений
    ПО взСтрокиИнтервалов.НомерСтроки = тмпРегистрСведений.НомерСтроки
    И взСтрокиИнтервалов.Флаг = тмпРегистрСведений.Флаг
    ИТОГИ
    МИНИМУМ(НомерСтроки) КАК НачалоИнтервала,
    МАКСИМУМ(НомерСтроки) КАК КонецИнтервала
    ПО
    НомерСтрокиДоИнтервала
```
---
Чем решение в (4) не угодило?
---
Здравствуйте!
Добавьте нумерацию строк в запросе
и выведите только те номера напротив которых истина, так и получите интервалы
если я правильно понял вопрос...
---
Так я вручную получу, а хотелось бы автоматически
---
ищите по "тэта-соединение"
---
См. https://www.youtube.com/watch?v=YyqfK9_GVic&list=LL&index=2
---
Ну держи. У меня это сейчас работает. Правда нельзя создать регистр с измерением "НомерСтроки", так что он у меня называется "НомерСтрокиРегистра". И еще, автор признайся, это задача с собеседования? Потому что я ума не приложу, где в реальной практике это может пригодиться. Такие абстрактные задачи обычно с собеседований тащат

```1c
    ВЫБРАТЬ
    РегистрНомеров.НомерСтрокиРегистра КАК НомерСтрокиРегистра,
    РегистрНомеров.Флаг КАК Флаг
    ПОМЕСТИТЬ ПервичнаяВыборка
    ИЗ
    РегистрСведений.РегистрНомеров КАК РегистрНомеров
    ГДЕ
    РегистрНомеров.Флаг
    ;

    ////////////////////////////////////////////////////////////­////////////////////
    ВЫБРАТЬ
    ПервичнаяВыборка.НомерСтрокиРегистра КАК НомерСтрокиРегистра,
    ЕСТЬNULL(ПервичнаяВыборкаСледующийНомер.Флаг, ЛОЖЬ) КАК ЕстьСледующийНомер,
    ЕСТЬNULL(ПервичнаяВыборкаПредыдущийНомер.Флаг, ЛОЖЬ) КАК ЕстьПредыдущийНомер
    ПОМЕСТИТЬ АнализНомеров
    ИЗ
    ПервичнаяВыборка КАК ПервичнаяВыборка
    ЛЕВОЕ СОЕДИНЕНИЕ ПервичнаяВыборка КАК ПервичнаяВыборкаСледующийНомер
    ПО (ПервичнаяВыборка.НомерСтрокиРегистра = ПервичнаяВыборкаСледующийНомер.НомерСтрокиРегистра + 1)
    ЛЕВОЕ СОЕДИНЕНИЕ ПервичнаяВыборка КАК ПервичнаяВыборкаПредыдущийНомер
    ПО (ПервичнаяВыборка.НомерСтрокиРегистра = ПервичнаяВыборкаПредыдущийНомер.НомерСтрокиРегистра - 1)
    ;

    ////////////////////////////////////////////////////////////­////////////////////
    ВЫБРАТЬ
    АнализНомеров.НомерСтрокиРегистра КАК НомерСтрокиРегистра,
    ВЫБОР
    КОГДА НЕ АнализНомеров.ЕстьСледующийНомер
    И НЕ АнализНомеров.ЕстьПредыдущийНомер
    ТОГДА ЛОЖЬ
    ИНАЧЕ ИСТИНА
    КОНЕЦ КАК ЭтоИнтервал
    ПОМЕСТИТЬ ВсеИнтервалы
    ИЗ
    АнализНомеров КАК АнализНомеров
    ГДЕ
    НЕ(АнализНомеров.ЕстьСледующийНомер
    И АнализНомеров.ЕстьПредыдущийНомер)
    ;

    ////////////////////////////////////////////////////////////­////////////////////
    ВЫБРАТЬ
    ВсеИнтервалы.НомерСтрокиРегистра КАК ПервыйНомерИнтервала,
    ВсеИнтервалы.НомерСтрокиРегистра КАК ВторойНомерИнтервала
    ПОМЕСТИТЬ ОдлиночныеИнтервалы
    ИЗ
    ВсеИнтервалы КАК ВсеИнтервалы
    ГДЕ
    НЕ ВсеИнтервалы.ЭтоИнтервал
    ;

    ////////////////////////////////////////////////////////////­////////////////////
    ВЫБРАТЬ
    ВсеИнтервалы.НомерСтрокиРегистра КАК НомерСтрокиРегистра
    ПОМЕСТИТЬ ДвойныеИнтервалыВСтолбец
    ИЗ
    ВсеИнтервалы КАК ВсеИнтервалы
    ГДЕ
    ВсеИнтервалы.ЭтоИнтервал
    ;

    ////////////////////////////////////////////////////////////­////////////////////
    ВЫБРАТЬ
    ВсеИнтервалы.НомерСтрокиРегистра КАК НомерСтрокиРегистра
    ПОМЕСТИТЬ ДвойныеИнтервалыПервыйНомер
    ИЗ
    ВсеИнтервалы КАК ВсеИнтервалы
    ЛЕВОЕ СОЕДИНЕНИЕ АнализНомеров КАК АнализНомеров
    ПО ВсеИнтервалы.НомерСтрокиРегистра = АнализНомеров.НомерСтрокиРегистра
    ГДЕ
    ВсеИнтервалы.ЭтоИнтервал
    И АнализНомеров.ЕстьПредыдущийНомер
    ;

    ////////////////////////////////////////////////////////////­////////////////////
    ВЫБРАТЬ
    ДвойныеИнтервалыПервыйНомер.НомерСтрокиРегистра КАК ПервыйНомерИнтервала,
    МИНИМУМ(ДвойныеИнтервалыВСтолбец.НомерСтрокиРегистра) КАК ВторойНомерИнтервала
    ПОМЕСТИТЬ ДвойныеИнтервалыВСтроку
    ИЗ
    ДвойныеИнтервалыПервыйНомер КАК ДвойныеИнтервалыПервыйНомер
    ЛЕВОЕ СОЕДИНЕНИЕ ДвойныеИнтервалыВСтолбец КАК ДвойныеИнтервалыВСтолбец
    ПО ДвойныеИнтервалыПервыйНомер.НомерСтрокиРегистра < ДвойныеИнтервалыВСтолбец.НомерСтрокиРегистра

    СГРУППИРОВАТЬ ПО
    ДвойныеИнтервалыПервыйНомер.НомерСтрокиРегистра
    ;

    ////////////////////////////////////////////////////////////­////////////////////
    ВЫБРАТЬ
    ОдлиночныеИнтервалы.ПервыйНомерИнтервала КАК ПервыйНомерИнтервала,
    ОдлиночныеИнтервалы.ВторойНомерИнтервала КАК ВторойНомерИнтервала
    ИЗ
    ОдлиночныеИнтервалы КАК ОдлиночныеИнтервалы

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

    ВЫБРАТЬ
    ДвойныеИнтервалыВСтроку.ПервыйНомерИнтервала,
    ДвойныеИнтервалыВСтроку.ВторойНомерИнтервала
    ИЗ
    ДвойныеИнтервалыВСтроку КАК ДвойныеИнтервалыВСтроку

    УПОРЯДОЧИТЬ ПО
    ПервыйНомерИнтервала
```
---
Достойно. Внушает.

И еще, автор признайся, это задача с собеседования?

К сожалению, это задача со служебного расследования. Решение проблемы 3-й степени, то есть проблемы, обнаружившейся при решении проблемы, обнаружившейся при решении задачи, поставленной аж Советом Директоров, то есть Людьми, стоящими на ступеньку повыше Гендира. И по результатам того, что я, надеюсь, накопаю, будет ещё 4-е расследование.

Текущая задача называется "Задави фантомные дубли", а оригинальная проблема "Почему у Вас в регистре период "едет"? ". Тут очень долго объяснять. бычно так говорят, когда не хотят объяснять, но в данном случае объяснять действительно долго.

В реальности задача ещё интереснее, но тут уж за решение надо настоящие деньги просить. Там надо:
1) взять строку на 1 меньше начала интервала и строку на 1 больше конца
2) обработать забег за начало или конец выборки
3) пробежаться по детальным записям под шапкой итогов и тем, чье поле PCR не лежит в интервале между значениями PCR из записей из п.1 - поставить некоторый флажок.
4) PCR при достижении 8 с чем-то миллиардов (2 в 33-ей степени) сбрасывается, поэтому надо ещё учитывать переход через 0, что даёт незабываемые ощущения, здесь у меня пока затык, но с этим вопросом уже не сюда.
---
Тогда вопрос - зачем это делать именно в запросе? Обработать выборку было бы гораздо проще и не факт, что запрос сработает быстрее.
---
Да я так и делаю. Тем более, что у меня цикл и так есть, где я флажок проставляю. У меня запросик попроще

```1c
    ВЫБРАТЬ
    ПорядокM3u8.ИмяTSФайлаСРасширением КАК ИмяTSФайлаСРасширением,
    КОЛИЧЕСТВО(ПорядокM3u8.ИмяM3u8) КАК Кол_во
    ПОМЕСТИТЬ ВТ_Повторы
    ИЗ
    РегистрСведений.ПорядокM3u8 КАК ПорядокM3u8
    ГДЕ
    ПорядокM3u8.ПодкаталогTS = &ПодкаталогTS

    СГРУППИРОВАТЬ ПО
    ПорядокM3u8.ИмяTSФайлаСРасширением
    ;

    ////////////////////////////////////////////////////////////­////////////////////
    ВЫБРАТЬ
    ВТ_Повторы.ИмяTSФайлаСРасширением КАК ИмяTSФайлаСРасширением,
    ВТ_Повторы.Кол_во КАК Кол_во
    ПОМЕСТИТЬ ВТ_ДляСвязи
    ИЗ
    ВТ_Повторы КАК ВТ_Повторы
    ГДЕ
    ВТ_Повторы.Кол_во > 1
    ;

    ////////////////////////////////////////////////////////////­////////////////////
    ВЫБРАТЬ
    ПорядокM3u8.ПодкаталогTS КАК ПодкаталогTS,
    ПорядокM3u8.НомерПоПорядку КАК НомерПоПорядку,
    ВТ_ДляСвязи.ИмяTSФайлаСРасширением КАК ИмяTSФайлаСРасширением
    ИЗ
    ВТ_ДляСвязи КАК ВТ_ДляСвязи
    ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.ПорядокM3u8 КАК ПорядокM3u8
    ПО ВТ_ДляСвязи.ИмяTSФайлаСРасширением = ПорядокM3u8.ИмяTSФайлаСРасширением
```

был бы HAVING() можно было бы в 2 запроса уложиться. Всё-таки жаль, что в 1С нет запросов на модификацию данных и приходится цикл крутить.

Зато сделал из лимона лимонад - заодно в цикле заполняется ТЗ с границами интервала, одна из колонок которой - с ключами детальных записей - то ли СЗ со структурами, то ли другая ТЗ - ещё не решил, как лучше. Собираю ключи, а потом в другом цикле буду по ним бегать, когда вопрос с переходом через 0 решу. Будет типа запроса в цикле, думал, что через запрос элегантнее будет.
---
Ну что же, удачи.
---
был бы HAVING() Так есть же. ИМЕЮЩИЕ
---
А в Конструкторе запросов он где?
---
в условиях, при условии, что есть группировка
---
В явном виде нет. Можно указать в виде произвольного условия на сравнение агрегатной функции

P.S. привыкайте к текстам запросов без конструктора.
P.S.S. Вообще в стандартной справке 1С (в конфигураторе которая) язык запросов довольно хорошо описан.
---
Можно указать в виде произвольного условия на сравнение агрегатной функции

Спасибо!

(18) P.S. привыкайте к текстам запросов без конструктора.

Да я почти всю свою жизнь жил в режиме "всё есть, только ничего нет", то есть вещь имеется, но для галочки, а пользоваться по прямому назначению нельзя. Только начал привыкать к сервису, а опять бьют по рукам. Жалко :(
---
Только начал привыкать к сервису, а опять бьют по рукам
ИМЕЮЩИЕ проще руками в тексте после конструктора дописать, там же можно агрегаты из группировки копипастить. Никогда их в условиях конструктора не рисую.
---
ещё надо

```1c
    УПОРЯДОЧИТЬ ПО
    ПодкаталогTS,
    НомерПоПорядку
```
---
опередил меня) я думал до вечера никто не сделает))
мой вариант:

```1c
    ВЫБРАТЬ
    Регистр.Номер КАК Номер,
    Регистр.Флаг КАК Флаг,
    ЕСТЬNULL(Регистр2.Флаг, ЛОЖЬ) КАК Следующее,
    ЕСТЬNULL(Регистр1.Флаг, ЛОЖЬ) КАК Предыдущее,
    ВЫБОР
    КОГДА Регистр.Флаг = ИСТИНА
    И Регистр2.Флаг = ИСТИНА
    И Регистр1.Флаг = ЛОЖЬ
    ИЛИ Регистр.Флаг = ИСТИНА
    И Регистр2.Флаг = ЛОЖЬ
    И Регистр1.Флаг = ИСТИНА
    ИЛИ Регистр.Флаг = ИСТИНА
    И Регистр2.Флаг = ЛОЖЬ
    И Регистр1.Флаг = ЛОЖЬ
    ТОГДА Регистр.Номер
    КОНЕЦ КАК НачалоКонец
    ПОМЕСТИТЬ ВТ_Периоды
    ИЗ
    РегистрСведений.Регистр КАК Регистр
    ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.Регистр КАК Регистр1
    ПО (Регистр.Номер = Регистр1.Номер + 1)
    ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.Регистр КАК Регистр2
    ПО (Регистр.Номер = Регистр2.Номер - 1)
    ;

    ////////////////////////////////////////////////////////////­////////////////////
    ВЫБРАТЬ
    ВТ_Периоды.Номер КАК НомерСтроки,
    ВТ_Периоды.Флаг КАК Флаг,
    МИНИМУМ(ВТ_Периоды.НачалоКонец) КАК Начало,
    МИНИМУМ(ВЫБОР
    КОГДА ВТ_Периоды.Следующее = ЛОЖЬ
    ТОГДА ВТ_Периоды.Номер
    ИНАЧЕ ВТ_Периоды1.НачалоКонец
    КОНЕЦ) КАК Конец
    ПОМЕСТИТЬ ВТ_НачалоКонец
    ИЗ
    ВТ_Периоды КАК ВТ_Периоды
    ЛЕВОЕ СОЕДИНЕНИЕ ВТ_Периоды КАК ВТ_Периоды1
    ПО ВТ_Периоды.Номер < ВТ_Периоды1.Номер
    ГДЕ
    НЕ ВТ_Периоды.НачалоКонец ЕСТЬ NULL
    И НЕ ВТ_Периоды1.НачалоКонец ЕСТЬ NULL

    СГРУППИРОВАТЬ ПО
    ВТ_Периоды.Номер,
    ВТ_Периоды.Флаг
    ;

    ////////////////////////////////////////////////////////////­////////////////////
    ВЫБРАТЬ
    ВТ_НачалоКонец.НомерСтроки КАК НомерСтроки,
    ВТ_НачалоКонец.Флаг КАК Флаг,
    ВТ_НачалоКонец.Начало КАК Начало,
    ВТ_НачалоКонец.Конец КАК Конец
    ИЗ
    ВТ_НачалоКонец КАК ВТ_НачалоКонец

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

    ВЫБРАТЬ
    Регистр.Номер,
    Регистр.Флаг,
    Регистр.Номер,
    Регистр.Номер
    ИЗ
    РегистрСведений.Регистр КАК Регистр
    ГДЕ
    НЕ Регистр.Флаг

    УПОРЯДОЧИТЬ ПО
    НомерСтроки
```
---
Ну, если Вам так охота блеснуть, то задача усложняется. Оригинальная задача гласит:

1. В игру вводится числовой неотрицательный ресурс "PCR". Требуется для каждого интервала:

- взять PCR из записи перед началом интервала (НомерСтроки=НачалоИнтервала-1), назовём его PCRmin. Обработать случай, когда интервал стоИт в начале выборки и этой записи нет;

- взять PCR из записи после конца интервала (НомерСтроки=КонецИнтервала+1), назовём его PCRmax. Обработать случай, когда интервал стоИт в конце выборки и этой записи нет;

- пройти по интервалу и сгенерировать список из номеров строк, где PCR НЕ МЕЖДУ PCRmin И PCRmax **) и удалить их из выборки для выполнения следующего шага.

2. Мой любимый момент. В игру вводится символьный ресурс "ИмяTSФайла". Если в интервале а) несколько записей с одним именем файла и б) которые ВЛЕЗАЮТ МЕЖДУ PCRmin И PCRmax **) (иначе бы они вылетели на предыдущем шаге), требуется оставить из них тот (то есть в поместить в список номеров строк остальные дубли имён), при котором НЕ нарушается возрастание PCR **) во всём интервале. Самое интересное №1, что таких дублей в интервале может быть несколько и имён файлов с дублями то же может быть несколько, поэтому решение, какой номер строки оставить по одному имени влияет на остальные имена плюс там ещё могут быть не-дубли, оставленные на предыдущем шаге. Требуется принимать решение для всех дублей по всему интервалу в целом. Тут светит либо метод перебора либо лично я вспомнил институтские годы чудесные и использовал аж градиентный спуск. Не в запросе, разумеется. Самое интересное №2, что при некоторых раскладах задача может не иметь решения и требуется продетектировать это момент и сигнализировать о нём.

**) А вот и задача с двумя звёздочками - PCR представляет собой 33-битное число и меняется в диапазоне от 0 до 2 в 33-ей степени (8 589 934 592 - и это НЕ номер телефона ;) ), то есть, если PCR превышает 8 589 934 592 из него как бы вычитается 8 589 934 592. Ну, или PCR представляет собой остаток от деления некого числа на 8 589 934 592.

Требуется учесть и этот момент. Задача немного облегчается, если выборка идёт за сутки. 1 секунда = 90 000, поэтому PCR обнуляется каждые 99 420,5... секунд, то есть, если повезёт, перехода через 0 может вообще не быть, а если он есть - тогда он гарантировано один, и его отловить относительно легко. Но если выборка за неделю, тогда таких переходов гарантировано будет несколько и на период опираться нельзя, поскольку он неправильный - его-то как раз и исправляем.

P.S. А кто-то говорил "собеседование". Жизнь ставит такие задачи, что никакому обкурившемуся экзаменатору во сне не приснятся. Самое интересное, что это лишь вспомогательная задача для решения другой вспомогательной задачи.
---
Жизнь ставит такие задачи, что никакому обкурившемуся экзаменатору во сне не приснятся.Архитектору решения кол с минусом.(24) Самое интересное, что это лишь вспомогательная задача для решения другой вспомогательной задачи.см. выше.
А в целом вопрос: "Зачем?"
Ради спортивного интереса? Обработать програмно будет быстрее 100%
Если правильно понял задачу, то всего 2 прохода по выборке.
---
Архитектору решения кол с минусом

Согласен. Ваши рекомендации?

(28) А в целом вопрос: "Зачем?"

А вдруг есть решение проще, которое я не вижу? Например, не надо группировать руками, когда есть итоги. Вдруг и тут есть что-нибудь, что облегчит мою участь?

(28) Если правильно понял задачу, то всего 2 прохода по выборке.

Ну да, только второй цикл хитрый. Сформировали интервал, сразу предали на обработку. Там взяли предыдущую и последующую запись (2 неявных запроса в цикле, от которых я так хотел уйти) и ещё цикл, чтобы убить тех, кто по PCR не пролазит и набить портянку для градиента, чтобы, когда в интервал попадёт несколько дублей сразу,то в живых остался не нарушающий последовательность. Для оптимизации при добавлении в портянку по флажку отслеживаем, были дубли или нет. И если были - крутим по портянке пародию на градиент - ещё 2 вложенных цикла. Примерно как-то так. Работает быстро.
---
Забыл написать PCR связано с "ИмяTSФайла", то есть, если имя файла совпадает, то PCR тоже совпадает
---
"Ох, и запросики у вас, сказала база и зависла" )

Собрал запрос, из спортивного интереса.
Все условия вывел в отдельные поля, для наглядности. Чтобы видно было, что потом отрезать.
Отслеживание перехода через ноль при переполнении типа осуществлён по разнице значений PCR больше 100 000 000.

```1c
    ВЫБРАТЬ
    тз.НомерСтроки КАК НомерСтроки,
    тз.Флаг КАК Флаг,
    тз.PCR КАК PCR,
    тз.ИмяTSФайла КАК ИмяTSФайла
    ПОМЕСТИТЬ тмпРС
    ИЗ
    &тз КАК тз
    ;

    ////////////////////////////////////////////////////////////­////////////////////
    ВЫБРАТЬ
    ВЗ.НомерСтроки КАК НомерСтроки,
    1 КАК Переход0
    ПОМЕСТИТЬ тмпВыборкаПереходовНуля
    ИЗ
    (ВЫБРАТЬ
    тмпРС.НомерСтроки КАК НомерСтроки,
    МАКСИМУМ(ЕСТЬNULL(тмпРС_ПредыдущиеСтроки.НомерСтроки, 0)) КАК НомерСтрокиПред,
    тмпРС.PCR КАК PCR
    ИЗ
    тмпРС КАК тмпРС
    ЛЕВОЕ СОЕДИНЕНИЕ тмпРС КАК тмпРС_ПредыдущиеСтроки
    ПО тмпРС.НомерСтроки > тмпРС_ПредыдущиеСтроки.НомерСтроки

    СГРУППИРОВАТЬ ПО
    тмпРС.НомерСтроки,
    тмпРС.PCR) КАК ВЗ
    ЛЕВОЕ СОЕДИНЕНИЕ тмпРС КАК тмпРС
    ПО ВЗ.НомерСтрокиПред = тмпРС.НомерСтроки
    ГДЕ
    тмпРС.PCR - ВЗ.PCR > 100000000
    ;

    ////////////////////////////////////////////////////////////­////////////////////
    ВЫБРАТЬ
    тмпРС.НомерСтроки КАК НомерСтроки,
    тмпРС.Флаг КАК Флаг,
    тмпРС.PCR КАК PCR,
    КОЛИЧЕСТВО(РАЗЛИЧНЫЕ тмпВыборкаПереходовНуля.НомерСтроки) КАК Переход0
    ПОМЕСТИТЬ тмпВыборкаИнтервалов
    ИЗ
    тмпРС КАК тмпРС
    ЛЕВОЕ СОЕДИНЕНИЕ тмпВыборкаПереходовНуля КАК тмпВыборкаПереходовНуля
    ПО тмпРС.НомерСтроки >= тмпВыборкаПереходовНуля.НомерСтроки

    СГРУППИРОВАТЬ ПО
    тмпРС.НомерСтроки,
    тмпРС.Флаг,
    тмпРС.PCR

    ИНДЕКСИРОВАТЬ ПО
    Флаг,
    НомерСтроки
    ;

    ////////////////////////////////////////////////////////////­////////////////////
    ВЫБРАТЬ
    ВЗ.НомерСтроки КАК НомерСтроки,
    ВЗ.PCR КАК PCR,
    ВЗ.НомерСтрокиДоИнтервала КАК НомерСтрокиДоИнтервала,
    ВЗ.НомерСтрокиПослеИнтервала КАК НомерСтрокиПослеИнтервала,
    ВЗ.Переход0 КАК Переход0,
    тмпДоИнтервала.PCR КАК PCRmin,
    тмпДоИнтервала.Переход0 КАК Переход0_PCRmin,
    тмпПослеИнтервала.PCR КАК PCRmax,
    тмпПослеИнтервала.Переход0 КАК Переход0_PCRmax,
    тмпДоИнтервала.PCR ЕСТЬ NULL
    ИЛИ (ВЗ.Переход0 > тмпДоИнтервала.Переход0
    ИЛИ ВЗ.Переход0 = тмпДоИнтервала.Переход0
    И ВЗ.PCR >= тмпДоИнтервала.PCR)
    И (тмпПослеИнтервала.PCR ЕСТЬ NULL
    ИЛИ (ВЗ.Переход0 < тмпПослеИнтервала.Переход0
    ИЛИ ВЗ.Переход0 = тмпПослеИнтервала.Переход0
    И ВЗ.PCR <= тмпПослеИнтервала.PCR)) КАК PCRМежду_min_max
    ПОМЕСТИТЬ тмпИнтервалы
    ИЗ
    (ВЫБРАТЬ
    тмпВыборкаА_СтрокиИнтервалов.НомерСтроки КАК НомерСтроки,
    тмпВыборкаА_СтрокиИнтервалов.Переход0 КАК Переход0,
    тмпВыборкаА_СтрокиИнтервалов.Флаг КАК Флаг,
    тмпВыборкаА_СтрокиИнтервалов.PCR КАК PCR,
    МАКСИМУМ(тмпВыборкаБ_СтрокиДоИнтервала.НомерСтроки) КАК НомерСтрокиДоИнтервала,
    МИНИМУМ(тмпВыборкаВ_СтрокиПослеИнтервала.НомерСтроки) КАК НомерСтрокиПослеИнтервала
    ИЗ
    тмпВыборкаИнтервалов КАК тмпВыборкаА_СтрокиИнтервалов
    ЛЕВОЕ СОЕДИНЕНИЕ тмпВыборкаИнтервалов КАК тмпВыборкаБ_СтрокиДоИнтервала
    ПО (тмпВыборкаБ_СтрокиДоИнтервала.Флаг = ЛОЖЬ)
    И тмпВыборкаА_СтрокиИнтервалов.НомерСтроки > тмпВыборкаБ_СтрокиДоИнтервала.НомерСтроки
    ЛЕВОЕ СОЕДИНЕНИЕ тмпВыборкаИнтервалов КАК тмпВыборкаВ_СтрокиПослеИнтервала
    ПО (тмпВыборкаВ_СтрокиПослеИнтервала.Флаг = ЛОЖЬ)
    И тмпВыборкаА_СтрокиИнтервалов.НомерСтроки < тмпВыборкаВ_СтрокиПослеИнтервала.НомерСтроки
    ГДЕ
    тмпВыборкаА_СтрокиИнтервалов.Флаг = ИСТИНА

    СГРУППИРОВАТЬ ПО
    тмпВыборкаА_СтрокиИнтервалов.НомерСтроки,
    тмпВыборкаА_СтрокиИнтервалов.Переход0,
    тмпВыборкаА_СтрокиИнтервалов.Флаг,
    тмпВыборкаА_СтрокиИнтервалов.PCR) КАК ВЗ
    ЛЕВОЕ СОЕДИНЕНИЕ тмпВыборкаИнтервалов КАК тмпДоИнтервала
    ПО ВЗ.НомерСтрокиДоИнтервала = тмпДоИнтервала.НомерСтроки
    ЛЕВОЕ СОЕДИНЕНИЕ тмпВыборкаИнтервалов КАК тмпПослеИнтервала
    ПО ВЗ.НомерСтрокиПослеИнтервала = тмпПослеИнтервала.НомерСтроки
    ;

    ////////////////////////////////////////////////////////////­////////////////////
    ВЫБРАТЬ
    тмпИнтервалы.НомерСтроки КАК НомерСтроки,
    тмпИнтервалы.НомерСтрокиДоИнтервала КАК НомерСтрокиДоИнтервала,
    тмпИнтервалы.PCR КАК PCR,
    тмпИнтервалы.Переход0 КАК Переход0,
    Дубли_ИмяTSФайла_ВИнтервалах.ИмяTSФайла КАК ИмяTSФайла,
    тмпИнтервалы.PCRМежду_min_max КАК PCRМежду_min_max
    ПОМЕСТИТЬ тмпДубли_ИмяTSФайла_ВИнтервалах
    ИЗ
    тмпИнтервалы КАК тмпИнтервалы
    ВНУТРЕННЕЕ СОЕДИНЕНИЕ (ВЫБРАТЬ
    тмпИнтервалы.НомерСтрокиДоИнтервала КАК НомерСтрокиДоИнтервала,
    тмпРС.ИмяTSФайла КАК ИмяTSФайла
    ИЗ
    тмпИнтервалы КАК тмпИнтервалы
    ВНУТРЕННЕЕ СОЕДИНЕНИЕ тмпРС КАК тмпРС
    ПО тмпИнтервалы.НомерСтроки = тмпРС.НомерСтроки
    ГДЕ
    тмпИнтервалы.PCRМежду_min_max

    СГРУППИРОВАТЬ ПО
    тмпИнтервалы.НомерСтрокиДоИнтервала,
    тмпРС.ИмяTSФайла

    ИМЕЮЩИЕ
    КОЛИЧЕСТВО(1) > 1) КАК Дубли_ИмяTSФайла_ВИнтервалах
    ПО тмпИнтервалы.НомерСтрокиДоИнтервала = Дубли_ИмяTSФайла_ВИнтервалах.НомерСтрокиДоИнтервала

    ИНДЕКСИРОВАТЬ ПО
    НомерСтрокиДоИнтервала,
    НомерСтроки
    ;

    ////////////////////////////////////////////////////////////­////////////////////
    ВЫБРАТЬ
    тмпИнтервалы.НомерСтрокиДоИнтервала КАК НомерСтрокиДоИнтервала,
    тмпИнтервалы.НомерСтрокиПослеИнтервала КАК НомерСтрокиПослеИнтервала,
    тмпИнтервалы.НомерСтроки КАК НомерСтроки,
    тмпРС.Флаг КАК Флаг,
    тмпРС.PCR КАК PCR,
    тмпРС.ИмяTSФайла КАК ИмяTSФайла,
    тмпИнтервалы.PCRМежду_min_max КАК PCRМежду_min_max,
    ЕСТЬNULL(СтрокиСДублями_ИмяTSФайла.ДубльПоИмяTSФайла, ЛОЖЬ) КАК ДубльПоИмяTSФайла,
    ЕСТЬNULL(СтрокиСДублями_ИмяTSФайла.PCRПоПорядку, ИСТИНА) КАК PCRПоПорядку,
    NULL КАК КоличествоСтрокВИнтервале
    ИЗ
    тмпРС КАК тмпРС
    ВНУТРЕННЕЕ СОЕДИНЕНИЕ тмпИнтервалы КАК тмпИнтервалы
    ЛЕВОЕ СОЕДИНЕНИЕ (ВЫБРАТЬ
    СтрокиПоДублям.НомерСтроки КАК НомерСтроки,
    ИСТИНА КАК ДубльПоИмяTSФайла,
    СтрокиПоДублям.Переход0 > тмпДубли_ИмяTSФайла_ВИнтервалах.Переход0
    ИЛИ СтрокиПоДублям.Переход0 = тмпДубли_ИмяTSФайла_ВИнтервалах.Переход0
    И СтрокиПоДублям.PCR >= тмпДубли_ИмяTSФайла_ВИнтервалах.PCR КАК PCRПоПорядку
    ИЗ
    (ВЫБРАТЬ
    тмпДубли_ИмяTSФайла_ВИнтервалах.НомерСтроки КАК НомерСтроки,
    тмпДубли_ИмяTSФайла_ВИнтервалах.НомерСтрокиДоИнтервала КАК НомерСтрокиДоИнтервала,
    МАКСИМУМ(тмпДубли_ИмяTSФайла_ВИнтервалах_ПредыдущиеСтроки.НомерСтроки) КАК НомерСтрокиПред,
    тмпДубли_ИмяTSФайла_ВИнтервалах.PCR КАК PCR,
    тмпДубли_ИмяTSФайла_ВИнтервалах.Переход0 КАК Переход0
    ИЗ
    тмпДубли_ИмяTSФайла_ВИнтервалах КАК тмпДубли_ИмяTSФайла_ВИнтервалах
    ВНУТРЕННЕЕ СОЕДИНЕНИЕ тмпДубли_ИмяTSФайла_ВИнтервалах КАК тмпДубли_ИмяTSФайла_ВИнтервалах_ПредыдущиеСтроки
    ПО тмпДубли_ИмяTSФайла_ВИнтервалах.НомерСтрокиДоИнтервала = тмпДубли_ИмяTSФайла_ВИнтервалах_ПредыдущиеСтроки.НомерСтрокиДоИнтервала
    И тмпДубли_ИмяTSФайла_ВИнтервалах.НомерСтроки > тмпДубли_ИмяTSФайла_ВИнтервалах_ПредыдущиеСтроки.НомерСтроки

    СГРУППИРОВАТЬ ПО
    тмпДубли_ИмяTSФайла_ВИнтервалах.НомерСтроки,
    тмпДубли_ИмяTSФайла_ВИнтервалах.НомерСтрокиДоИнтервала,
    тмпДубли_ИмяTSФайла_ВИнтервалах.PCR,
    тмпДубли_ИмяTSФайла_ВИнтервалах.Переход0) КАК СтрокиПоДублям
    ВНУТРЕННЕЕ СОЕДИНЕНИЕ тмпДубли_ИмяTSФайла_ВИнтервалах КАК тмпДубли_ИмяTSФайла_ВИнтервалах
    ПО СтрокиПоДублям.НомерСтрокиДоИнтервала = тмпДубли_ИмяTSФайла_ВИнтервалах.НомерСтрокиДоИнтервала
    И СтрокиПоДублям.НомерСтрокиПред = тмпДубли_ИмяTSФайла_ВИнтервалах.НомерСтроки) КАК СтрокиСДублями_ИмяTSФайла
    ПО тмпИнтервалы.НомерСтроки = СтрокиСДублями_ИмяTSФайла.НомерСтроки
    ПО тмпРС.НомерСтроки = тмпИнтервалы.НомерСтроки
    ИТОГИ
    КОЛИЧЕСТВО(1) КАК КоличествоСтрокВИнтервале
    ПО
    НомерСтрокиДоИнтервала
```
---
Шикарно. Жаль, что $m перечислить не даёт за труды.
---
Вот мне всегда внушали уважение люди, которые вместо пяти строк в цикле рисовали сто строк в запросе. Но доверия не внушали - только уважение (как к старшим).
---
Просто неохота в цикле кочевряжиться. Сразу проваливаюсь лет на 40 назад, в до-DBF-ную эпоху, когда писали свои базы данных самопального формата. А так как в компьютерных технологиях год идёт за 5, то сейчас это всё равно, что ездить на работу в карете, освещать кабинет восковыми свечами и писать отчёты начальству гусиным пером.

(27) Но доверия не внушали

как раз попался

```1c
    ДОБАВИТЬКДАТЕ(ДОБАВИТЬКДАТЕ(ДОБАВИТЬКДАТЕ(НАЧАЛОПЕРИОДА(ДОБАВИТЬКДАТЕ(ТВ_Программа.Период, ЧАС, -6), МЕСЯЦ), ЧАС, ЧАС(ДОБАВИТЬКДАТЕ(НАЧАЛОПЕРИОДА(ДОБАВИТЬКДАТЕ(ТВ_Программа.Период, ЧАС, -6), МЕСЯЦ), ЧАС, ДЕНЬ(ДОБАВИТЬКДАТЕ(ТВ_Программа.Период, ЧАС, -6)) + ЧАС(ДОБАВИТЬКДАТЕ(ТВ_Программа.Период, ЧАС, -6)) - 1))), ЧАС, 6), МИНУТА, 47) КАК ЭталонныйПериод
```

Закончу с Проблемой периода - через временные таблицы растащу.
---
Сразу проваливаюсь лет на 40 назад, в до-DBF-ную эпохуСейчас времена снова поменялись и рулят микросервисы, noSQL, брокеры сообщений. Роль СУБД - это просто хранилище, там сейчас простые селекты и инсерты, ибо проекты борются за производительность в облачной распределенной инфраструктуре. И там, поверьте, никто не пишет запрос для интервалов. А 1С-неги - да, они устарели в части подходов к разработке ПО лет на 20.
ЗЫ: открою маленький секрет. Сейчас очень важно написать быстрый и оптимальный код, и сделать это тоже нужно достаточно быстро. И код должен быть прост, т.е. его должно быть просто поддерживать, менять, расширять. Вот этот "прогрессивный" скульный запрос обладает всеми возможными минусами: он сложен, следовательно плохо поддерживаем; он большой, он требует более высокой квалификации, да и работает по всей видимости дольше.
---
Больше. В Access добавлять/изменять/удалять запросом было можно в начале 90-х во времена Win 3.1, в Dbase/Clipper/FoxBase/Foxpro групповые команды APPEND/REPLACE/DELETE FOR/WHILE были уже в начале 80-х. И как-то скучновато в эпоху нейросетей по старинке в цикле бегать
---
Это если не знать, из чего состоит перцептрон. Любая программа - это в той или иной мере цикл. Хотите новизны - идите программировать на RUST, GO, Python, зачем Вам 1С?
---
Я не хочу новизны, я хочу Инструмент, которым пользуешься и чувствуешь - вещь. Эргономика хромает. Смотришь - всё просто, начинаешь делать - это не работает, здесь нужно извращаться, это работает не так и борешься с инструментом вместо того, чтобы его использовать. Просто по инерции думаешь: "Ну не могут же такие простые вещи так сложно достигаться, наверное, я что-то где-то не доглядел". А выходит - и действительно - нету. И это страшно давит на психику.