Очередная серия "минимализмов" [http://infostart.ru/public/306536/, https://infostart.ru/public/460935/]. Также, как и в предыдущих статьях, здесь приведена подборка коротких оригинальных авторских решений некоторых задач. Ранее эти решения были разбросаны по моим комментариям к чужим публикациям.
Подскажите что можно взять за основу для определения интервалов чисел.
Например есть массив: 1,2,3,6,7,8,11,12,15.
Надо получить интервалы 1-3,6-8,11-12,15-15.
Определение суммарного покрытия перекрывающихся интервалов
Еще раз спасибо за это решение, очень выручила подсказка.
Нахождение на рабочем месте двумя способами (осторожно, много буков):
Скрытый текст
////////////////////////////////////////////////////////////////////////////////////////////////////
// Отбор рабочего времени использует метод Islands and Gaps,
// результат собирается из 2-х различных способов вычисления нахождения на рабочем месте
// (от каждого берется наибольшее значение)
// Входные параметры запроса:
// Дата - любая дата внутри месяца за который нужно получить рабочее время
// Сотрудник - сотрудник, по которому необходимо получить данные (если пустая ссылка, то по всем)
// Используемый регистр сведений содержит следующие измерения:
// Период, Время, Сотрудник, Дверь, Направление
////////////////////////////////////////////////////////////////////////////////////////////////////
//
//
////////////////////////////////////////////////////////////////////////////////////////////////////
// Делаю основную выборку данных по проходам из РС
////////////////////////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ
Сотрудник КАК Сотрудник,
Сотрудник.НормаВремениЗаСмену КАК НормаВремениЗаСмену,
Период КАК День,
ДобавитьКДате(Период, СЕКУНДА, РазностьДат(ДАТАВРЕМЯ(1, 1, 1), Время, СЕКУНДА)) КАК Дата,
Направление КАК Направление,
Дверь КАК Дверь,
ВЫБОР
КОГДА Сотрудник.НормаВремениЗаСмену >= 12
ТОГДА 9
ИНАЧЕ 6
КОНЕЦ КАК МинимальноеВремяДома
ПОМЕСТИТЬ ПроходыСигур
ИЗ
РегистрСведений.ПроходыСигур
ГДЕ
Период Между ДобавитьКДате(НачалоПериода(&Дата, МЕСЯЦ), ДЕНЬ, -2) И ДобавитьКДате(КонецПериода(&Дата, МЕСЯЦ), ДЕНЬ, 2)
И ВЫБОР
КОГДА &Сотрудник = Значение(Справочник.Сотрудники.ПустаяСсылка)
ТОГДА Истина
ИНАЧЕ Сотрудник = &Сотрудник
КОНЕЦ
;
//
//
////////////////////////////////////////////////////////////////////////////////////////////////////
// 1-ый способ расчета, ищутся пары Вход-Выход для входных дверей,
// которые вписываются в условие между 2 часами И (нормой времени за смену * 2 + 3)
////////////////////////////////////////////////////////////////////////////////////////////////////
// Добавляю к исходным данным за три дня до и после даты входа и выхода
// на случай если там ничего нет
// Например: выходные-праздники-отпуск
ВЫБРАТЬ Дата, Сотрудник, МинимальноеВремяДома
ПОМЕСТИТЬ Дано
ИЗ ПроходыСигур КАК ПроходыСигур
ОБЪЕДИНИТЬ ВСЕ
ВЫБРАТЬ РАЗЛИЧНЫЕ ДобавитьКДате(НачалоПериода(&Дата, МЕСЯЦ), ДЕНЬ, -3), Сотрудник, МинимальноеВремяДома
ИЗ ПроходыСигур КАК ПроходыСигур
ОБЪЕДИНИТЬ ВСЕ
ВЫБРАТЬ РАЗЛИЧНЫЕ ДобавитьКДате(КонецПериода(&Дата, МЕСЯЦ), ДЕНЬ, 3), Сотрудник, МинимальноеВремяДома
ИЗ ПроходыСигур КАК ПроходыСигур
ИНДЕКСИРОВАТЬ ПО Дата, Сотрудник
;
////////////////////////////////////////////////////////////////////////////////////////////////////
// Отбираю периоды 'отсутсвий' на работе больше N часов
ВЫБРАТЬ
Максимум(Раньше.Дата) КАК От,
Дано.Дата КАК До,
Дано.Сотрудник КАК Сотрудник,
Дано.МинимальноеВремяДома КАК МинимальноеВремяДома
ПОМЕСТИТЬ Отсутствия
ИЗ
Дано КАК Раньше
ВНУТРЕННЕЕ СОЕДИНЕНИЕ Дано КАК Дано
ПО Раньше.Сотрудник = Дано.Сотрудник
И Раньше.Дата < Дано.Дата
СГРУППИРОВАТЬ ПО
Дано.Сотрудник,
Дано.Дата,
Дано.МинимальноеВремяДома
ИМЕЮЩИЕ
РазностьДат(Максимум(Раньше.Дата), Дано.Дата, ЧАС) > Дано.МинимальноеВремяДома
ИНДЕКСИРОВАТЬ ПО Сотрудник, От, До
;
УНИЧТОЖИТЬ Дано
;
////////////////////////////////////////////////////////////////////////////////////////////////////
// Строю присутсвия на основании отсутсвий
ВЫБРАТЬ
Отсутствия.Сотрудник КАК Сотрудник,
Максимум(Раньше.До) КАК От,
Отсутствия.От КАК До,
ПроходыСигур.НормаВремениЗаСмену КАК НормаВремениЗаСмену
ПОМЕСТИТЬ НахождениеНаРаботе
ИЗ
Отсутствия КАК Отсутствия
ВНУТРЕННЕЕ СОЕДИНЕНИЕ Отсутствия КАК Раньше
ПО Отсутствия.Сотрудник = Раньше.Сотрудник И Раньше.До < Отсутствия.От
ВНУТРЕННЕЕ СОЕДИНЕНИЕ ПроходыСигур КАК ПроходыСигур
ПО Отсутствия.Сотрудник = ПроходыСигур.Сотрудник
СГРУППИРОВАТЬ ПО
Отсутствия.От,
Отсутствия.Сотрудник,
ПроходыСигур.НормаВремениЗаСмену
;
УНИЧТОЖИТЬ Отсутствия
;
////////////////////////////////////////////////////////////////////////////////////////////////////
// Получаю результат способа 1
ВЫБРАТЬ
Сотрудник КАК Сотрудник,
День(От) КАК День,
От КАК От,
До КАК До,
ВЫБОР
КОГДА РазностьДат(От, До, МИНУТА)/60 МЕЖДУ 24 И НормаВремениЗаСмену*2+3
ТОГДА 24
ИНАЧЕ РазностьДат(От, До, МИНУТА)/60
КОНЕЦ КАК ЧасовНаРаботе,
НормаВремениЗаСмену КАК НормаВремениЗаСмену
ПОМЕСТИТЬ Способ1
ИЗ НахождениеНаРаботе
ГДЕ
От Между НачалоПериода(&Дата, МЕСЯЦ) И КонецПериода(&Дата, МЕСЯЦ)
И РазностьДат(От, До, ЧАС) МЕЖДУ 2 И НормаВремениЗаСмену*2+3
;
УНИЧТОЖИТЬ НахождениеНаРаботе
;
//
//
////////////////////////////////////////////////////////////////////////////////////////////////////
// 2-ый способ расчета, ищутся пары Вход-Выход для входных дверей,
// которые вписываются в условие между 2 часами и нормой времени за смену * 1.5
////////////////////////////////////////////////////////////////////////////////////////////////////
// Собираю данные по входам, беру только двери ведущие на внешнюю территорию
ВЫБРАТЬ Сотрудник, НормаВремениЗаСмену, День, Дата
ПОМЕСТИТЬ Входы
ИЗ ПроходыСигур
ГДЕ
Направление = Значение(Перечисление.НаправлениеПроходаСигур.Вход)
И Дверь В(Значение(Перечисление.ДвериСигур.Дверь04), Значение(Перечисление.ДвериСигур.Дверь07))
ИНДЕКСИРОВАТЬ ПО Сотрудник, Дата
;
////////////////////////////////////////////////////////////////////////////////////////////////////
// Собираю данные по выходам, беру только двери ведущие на внешнюю территорию,
// а также расчитываю МинДатаВхода - означающае минимальную дату входа в пару к текущему выходу
ВЫБРАТЬ
Сотрудник, Дата,
ДобавитьКДате(Дата, ЧАС, -НормаВремениЗаСмену*1.5) КАК МинДатаВхода
ПОМЕСТИТЬ Выходы
ИЗ ПроходыСигур
ГДЕ
Направление = Значение(Перечисление.НаправлениеПроходаСигур.Выход)
И Дверь В(Значение(Перечисление.ДвериСигур.Дверь04), Значение(Перечисление.ДвериСигур.Дверь07))
;
УНИЧТОЖИТЬ ПроходыСигур
;
////////////////////////////////////////////////////////////////////////////////////////////////////
// Собираю все возможные и допустимые пары Вход/Выход
ВЫБРАТЬ
Входы.Сотрудник КАК Сотрудник,
Входы.НормаВремениЗаСмену КАК НормаВремениЗаСмену,
Входы.День КАК День,
Входы.Дата КАК От,
Выходы.Дата КАК До,
Максимум(РазностьДат(Входы.Дата, Выходы.Дата, МИНУТА)/60) КАК ЧасовНаРаботе
ПОМЕСТИТЬ ВозможныеПериоды
ИЗ
Входы КАК Входы
ВНУТРЕННЕЕ СОЕДИНЕНИЕ Выходы КАК Выходы
ПО Входы.Сотрудник = Выходы.Сотрудник
И Входы.Дата МЕЖДУ Выходы.МинДатаВхода И Выходы.Дата
СГРУППИРОВАТЬ ПО
Входы.Сотрудник, Входы.НормаВремениЗаСмену, Входы.День, Входы.Дата, Выходы.Дата
ИМЕЮЩИЕ
Максимум(РазностьДат(Входы.Дата, Выходы.Дата, МИНУТА)/60) МЕЖДУ 2 И НормаВремениЗаСмену*2+3
;
УНИЧТОЖИТЬ Входы
;
УНИЧТОЖИТЬ Выходы
;
ВЫБРАТЬ
ВозможныеПериоды.Сотрудник КАК Сотрудник,
День(ВозможныеПериоды.День) КАК День,
ВозможныеПериоды.От КАК От,
ВозможныеПериоды.До КАК До,
ВозможныеПериоды.ЧасовНаРаботе КАК ЧасовНаРаботе,
ВозможныеПериоды.НормаВремениЗаСмену КАК НормаВремениЗаСмену
ПОМЕСТИТЬ Способ2
ИЗ
ВозможныеПериоды КАК ВозможныеПериоды
ГДЕ
От Между НачалоПериода(&Дата, МЕСЯЦ) И КонецПериода(&Дата, МЕСЯЦ)
;
УНИЧТОЖИТЬ ВозможныеПериоды
;
//
//
////////////////////////////////////////////////////////////////////////////////////////////////////
// Объединяю данные двух запросов и привожу к ожидаемому виду
////////////////////////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ *
ПОМЕСТИТЬ Общее
ИЗ Способ1
ОБЪЕДИНИТЬ ВСЕ
ВЫБРАТЬ *
ИЗ Способ2
;
УНИЧТОЖИТЬ Способ1
;
УНИЧТОЖИТЬ Способ2
;
////////////////////////////////////////////////////////////////////////////////////////////////////
// После объединения оставляю только наибольшее зарегистрированное отработаное время,
// а также вычитаю час на обед для 8 часовой смены
// (если они находились на работе не меньше своей нормы - 2 часа)
ВЫБРАТЬ
ОбщееМакс.Сотрудник КАК Сотрудник,
ОбщееМакс.День КАК День,
Общее.От КАК От,
Общее.До КАК До,
ВЫБОР // ОбщееМакс.ЧасовНаРаботе,
КОГДА ОбщееМакс.ЧасовНаРаботе > Общее.НормаВремениЗаСмену-2 //
И Общее.НормаВремениЗаСмену < 12 //
ТОГДА ОбщееМакс.ЧасовНаРаботе-1 //
ИНАЧЕ ОбщееМакс.ЧасовНаРаботе //
КОНЕЦ КАК ЧасовНаРаботе, //
Общее.НормаВремениЗаСмену КАК НормаВремениЗаСмену
ПОМЕСТИТЬ Результат
ИЗ
Общее КАК Общее
ПРАВОЕ СОЕДИНЕНИЕ
(ВЫБРАТЬ Сотрудник, День, Максимум(ЧасовНаРаботе) КАК ЧасовНаРаботе
ИЗ Общее СГРУППИРОВАТЬ ПО Сотрудник, День) КАК ОбщееМакс
ПО Общее.Сотрудник = ОбщееМакс.Сотрудник
И Общее.День = ОбщееМакс.День
И Общее.ЧасовНаРаботе = ОбщееМакс.ЧасовНаРаботе
ИНДЕКСИРОВАТЬ ПО
ОбщееМакс.Сотрудник
;
УНИЧТОЖИТЬ Общее
;
////////////////////////////////////////////////////////////////////////////////////////////////////
// Компоную по дням, а также добавляю правым соединением сотрудников у которых небыло проходов
ВЫБРАТЬ
С.Ссылка КАК Сотрудник,
С.Группа КАК Группа,
Максимум(ВЫБОР КОГДА Р.День = 01 ТОГДА Р.От ИНАЧЕ 0 КОНЕЦ) КАК Ч1_От,
Максимум(ВЫБОР КОГДА Р.День = 01 ТОГДА Р.До ИНАЧЕ 0 КОНЕЦ) КАК Ч1_До,
Максимум(ВЫБОР КОГДА Р.День = 01 ТОГДА Р.ЧасовНаРаботе ИНАЧЕ 0 КОНЕЦ) КАК Ч1,
Максимум(ВЫБОР КОГДА Р.День = 02 ТОГДА Р.От ИНАЧЕ 0 КОНЕЦ) КАК Ч2_От,
Максимум(ВЫБОР КОГДА Р.День = 02 ТОГДА Р.До ИНАЧЕ 0 КОНЕЦ) КАК Ч2_До,
Максимум(ВЫБОР КОГДА Р.День = 02 ТОГДА Р.ЧасовНаРаботе ИНАЧЕ 0 КОНЕЦ) КАК Ч2,
Максимум(ВЫБОР КОГДА Р.День = 03 ТОГДА Р.От ИНАЧЕ 0 КОНЕЦ) КАК Ч3_От,
Максимум(ВЫБОР КОГДА Р.День = 03 ТОГДА Р.До ИНАЧЕ 0 КОНЕЦ) КАК Ч3_До,
Максимум(ВЫБОР КОГДА Р.День = 03 ТОГДА Р.ЧасовНаРаботе ИНАЧЕ 0 КОНЕЦ) КАК Ч3,
Максимум(ВЫБОР КОГДА Р.День = 04 ТОГДА Р.От ИНАЧЕ 0 КОНЕЦ) КАК Ч4_От,
Максимум(ВЫБОР КОГДА Р.День = 04 ТОГДА Р.До ИНАЧЕ 0 КОНЕЦ) КАК Ч4_До,
Максимум(ВЫБОР КОГДА Р.День = 04 ТОГДА Р.ЧасовНаРаботе ИНАЧЕ 0 КОНЕЦ) КАК Ч4,
Максимум(ВЫБОР КОГДА Р.День = 05 ТОГДА Р.От ИНАЧЕ 0 КОНЕЦ) КАК Ч5_От,
Максимум(ВЫБОР КОГДА Р.День = 05 ТОГДА Р.До ИНАЧЕ 0 КОНЕЦ) КАК Ч5_До,
Максимум(ВЫБОР КОГДА Р.День = 05 ТОГДА Р.ЧасовНаРаботе ИНАЧЕ 0 КОНЕЦ) КАК Ч5,
Максимум(ВЫБОР КОГДА Р.День = 06 ТОГДА Р.От ИНАЧЕ 0 КОНЕЦ) КАК Ч6_От,
Максимум(ВЫБОР КОГДА Р.День = 06 ТОГДА Р.До ИНАЧЕ 0 КОНЕЦ) КАК Ч6_До,
Максимум(ВЫБОР КОГДА Р.День = 06 ТОГДА Р.ЧасовНаРаботе ИНАЧЕ 0 КОНЕЦ) КАК Ч6,
Максимум(ВЫБОР КОГДА Р.День = 07 ТОГДА Р.От ИНАЧЕ 0 КОНЕЦ) КАК Ч7_От,
Максимум(ВЫБОР КОГДА Р.День = 07 ТОГДА Р.До ИНАЧЕ 0 КОНЕЦ) КАК Ч7_До,
Максимум(ВЫБОР КОГДА Р.День = 07 ТОГДА Р.ЧасовНаРаботе ИНАЧЕ 0 КОНЕЦ) КАК Ч7,
Максимум(ВЫБОР КОГДА Р.День = 08 ТОГДА Р.От ИНАЧЕ 0 КОНЕЦ) КАК Ч8_От,
Максимум(ВЫБОР КОГДА Р.День = 08 ТОГДА Р.До ИНАЧЕ 0 КОНЕЦ) КАК Ч8_До,
Максимум(ВЫБОР КОГДА Р.День = 08 ТОГДА Р.ЧасовНаРаботе ИНАЧЕ 0 КОНЕЦ) КАК Ч8,
Максимум(ВЫБОР КОГДА Р.День = 09 ТОГДА Р.От ИНАЧЕ 0 КОНЕЦ) КАК Ч9_От,
Максимум(ВЫБОР КОГДА Р.День = 09 ТОГДА Р.До ИНАЧЕ 0 КОНЕЦ) КАК Ч9_До,
Максимум(ВЫБОР КОГДА Р.День = 09 ТОГДА Р.ЧасовНаРаботе ИНАЧЕ 0 КОНЕЦ) КАК Ч9,
Максимум(ВЫБОР КОГДА Р.День = 10 ТОГДА Р.От ИНАЧЕ 0 КОНЕЦ) КАК Ч10_От,
Максимум(ВЫБОР КОГДА Р.День = 10 ТОГДА Р.До ИНАЧЕ 0 КОНЕЦ) КАК Ч10_До,
Максимум(ВЫБОР КОГДА Р.День = 10 ТОГДА Р.ЧасовНаРаботе ИНАЧЕ 0 КОНЕЦ) КАК Ч10,
Максимум(ВЫБОР КОГДА Р.День = 11 ТОГДА Р.От ИНАЧЕ 0 КОНЕЦ) КАК Ч11_От,
Максимум(ВЫБОР КОГДА Р.День = 11 ТОГДА Р.До ИНАЧЕ 0 КОНЕЦ) КАК Ч11_До,
Максимум(ВЫБОР КОГДА Р.День = 11 ТОГДА Р.ЧасовНаРаботе ИНАЧЕ 0 КОНЕЦ) КАК Ч11,
Максимум(ВЫБОР КОГДА Р.День = 12 ТОГДА Р.От ИНАЧЕ 0 КОНЕЦ) КАК Ч12_От,
Максимум(ВЫБОР КОГДА Р.День = 12 ТОГДА Р.До ИНАЧЕ 0 КОНЕЦ) КАК Ч12_До,
Максимум(ВЫБОР КОГДА Р.День = 12 ТОГДА Р.ЧасовНаРаботе ИНАЧЕ 0 КОНЕЦ) КАК Ч12,
Максимум(ВЫБОР КОГДА Р.День = 13 ТОГДА Р.От ИНАЧЕ 0 КОНЕЦ) КАК Ч13_От,
Максимум(ВЫБОР КОГДА Р.День = 13 ТОГДА Р.До ИНАЧЕ 0 КОНЕЦ) КАК Ч13_До,
Максимум(ВЫБОР КОГДА Р.День = 13 ТОГДА Р.ЧасовНаРаботе ИНАЧЕ 0 КОНЕЦ) КАК Ч13,
Максимум(ВЫБОР КОГДА Р.День = 14 ТОГДА Р.От ИНАЧЕ 0 КОНЕЦ) КАК Ч14_От,
Максимум(ВЫБОР КОГДА Р.День = 14 ТОГДА Р.До ИНАЧЕ 0 КОНЕЦ) КАК Ч14_До,
Максимум(ВЫБОР КОГДА Р.День = 14 ТОГДА Р.ЧасовНаРаботе ИНАЧЕ 0 КОНЕЦ) КАК Ч14,
Максимум(ВЫБОР КОГДА Р.День = 15 ТОГДА Р.От ИНАЧЕ 0 КОНЕЦ) КАК Ч15_От,
Максимум(ВЫБОР КОГДА Р.День = 15 ТОГДА Р.До ИНАЧЕ 0 КОНЕЦ) КАК Ч15_До,
Максимум(ВЫБОР КОГДА Р.День = 15 ТОГДА Р.ЧасовНаРаботе ИНАЧЕ 0 КОНЕЦ) КАК Ч15,
Максимум(ВЫБОР КОГДА Р.День = 16 ТОГДА Р.От ИНАЧЕ 0 КОНЕЦ) КАК Ч16_От,
Максимум(ВЫБОР КОГДА Р.День = 16 ТОГДА Р.До ИНАЧЕ 0 КОНЕЦ) КАК Ч16_До,
Максимум(ВЫБОР КОГДА Р.День = 16 ТОГДА Р.ЧасовНаРаботе ИНАЧЕ 0 КОНЕЦ) КАК Ч16,
Максимум(ВЫБОР КОГДА Р.День = 17 ТОГДА Р.От ИНАЧЕ 0 КОНЕЦ) КАК Ч17_От,
Максимум(ВЫБОР КОГДА Р.День = 17 ТОГДА Р.До ИНАЧЕ 0 КОНЕЦ) КАК Ч17_До,
Максимум(ВЫБОР КОГДА Р.День = 17 ТОГДА Р.ЧасовНаРаботе ИНАЧЕ 0 КОНЕЦ) КАК Ч17,
Максимум(ВЫБОР КОГДА Р.День = 18 ТОГДА Р.От ИНАЧЕ 0 КОНЕЦ) КАК Ч18_От,
Максимум(ВЫБОР КОГДА Р.День = 18 ТОГДА Р.До ИНАЧЕ 0 КОНЕЦ) КАК Ч18_До,
Максимум(ВЫБОР КОГДА Р.День = 18 ТОГДА Р.ЧасовНаРаботе ИНАЧЕ 0 КОНЕЦ) КАК Ч18,
Максимум(ВЫБОР КОГДА Р.День = 19 ТОГДА Р.От ИНАЧЕ 0 КОНЕЦ) КАК Ч19_От,
Максимум(ВЫБОР КОГДА Р.День = 19 ТОГДА Р.До ИНАЧЕ 0 КОНЕЦ) КАК Ч19_До,
Максимум(ВЫБОР КОГДА Р.День = 19 ТОГДА Р.ЧасовНаРаботе ИНАЧЕ 0 КОНЕЦ) КАК Ч19,
Максимум(ВЫБОР КОГДА Р.День = 20 ТОГДА Р.От ИНАЧЕ 0 КОНЕЦ) КАК Ч20_От,
Максимум(ВЫБОР КОГДА Р.День = 20 ТОГДА Р.До ИНАЧЕ 0 КОНЕЦ) КАК Ч20_До,
Максимум(ВЫБОР КОГДА Р.День = 20 ТОГДА Р.ЧасовНаРаботе ИНАЧЕ 0 КОНЕЦ) КАК Ч20,
Максимум(ВЫБОР КОГДА Р.День = 21 ТОГДА Р.От ИНАЧЕ 0 КОНЕЦ) КАК Ч21_От,
Максимум(ВЫБОР КОГДА Р.День = 21 ТОГДА Р.До ИНАЧЕ 0 КОНЕЦ) КАК Ч21_До,
Максимум(ВЫБОР КОГДА Р.День = 21 ТОГДА Р.ЧасовНаРаботе ИНАЧЕ 0 КОНЕЦ) КАК Ч21,
Максимум(ВЫБОР КОГДА Р.День = 22 ТОГДА Р.От ИНАЧЕ 0 КОНЕЦ) КАК Ч22_От,
Максимум(ВЫБОР КОГДА Р.День = 22 ТОГДА Р.До ИНАЧЕ 0 КОНЕЦ) КАК Ч22_До,
Максимум(ВЫБОР КОГДА Р.День = 22 ТОГДА Р.ЧасовНаРаботе ИНАЧЕ 0 КОНЕЦ) КАК Ч22,
Максимум(ВЫБОР КОГДА Р.День = 23 ТОГДА Р.От ИНАЧЕ 0 КОНЕЦ) КАК Ч23_От,
Максимум(ВЫБОР КОГДА Р.День = 23 ТОГДА Р.До ИНАЧЕ 0 КОНЕЦ) КАК Ч23_До,
Максимум(ВЫБОР КОГДА Р.День = 23 ТОГДА Р.ЧасовНаРаботе ИНАЧЕ 0 КОНЕЦ) КАК Ч23,
Максимум(ВЫБОР КОГДА Р.День = 24 ТОГДА Р.От ИНАЧЕ 0 КОНЕЦ) КАК Ч24_От,
Максимум(ВЫБОР КОГДА Р.День = 24 ТОГДА Р.До ИНАЧЕ 0 КОНЕЦ) КАК Ч24_До,
Максимум(ВЫБОР КОГДА Р.День = 24 ТОГДА Р.ЧасовНаРаботе ИНАЧЕ 0 КОНЕЦ) КАК Ч24,
Максимум(ВЫБОР КОГДА Р.День = 25 ТОГДА Р.От ИНАЧЕ 0 КОНЕЦ) КАК Ч25_От,
Максимум(ВЫБОР КОГДА Р.День = 25 ТОГДА Р.До ИНАЧЕ 0 КОНЕЦ) КАК Ч25_До,
Максимум(ВЫБОР КОГДА Р.День = 25 ТОГДА Р.ЧасовНаРаботе ИНАЧЕ 0 КОНЕЦ) КАК Ч25,
Максимум(ВЫБОР КОГДА Р.День = 26 ТОГДА Р.От ИНАЧЕ 0 КОНЕЦ) КАК Ч26_От,
Максимум(ВЫБОР КОГДА Р.День = 26 ТОГДА Р.До ИНАЧЕ 0 КОНЕЦ) КАК Ч26_До,
Максимум(ВЫБОР КОГДА Р.День = 26 ТОГДА Р.ЧасовНаРаботе ИНАЧЕ 0 КОНЕЦ) КАК Ч26,
Максимум(ВЫБОР КОГДА Р.День = 27 ТОГДА Р.От ИНАЧЕ 0 КОНЕЦ) КАК Ч27_От,
Максимум(ВЫБОР КОГДА Р.День = 27 ТОГДА Р.До ИНАЧЕ 0 КОНЕЦ) КАК Ч27_До,
Максимум(ВЫБОР КОГДА Р.День = 27 ТОГДА Р.ЧасовНаРаботе ИНАЧЕ 0 КОНЕЦ) КАК Ч27,
Максимум(ВЫБОР КОГДА Р.День = 28 ТОГДА Р.От ИНАЧЕ 0 КОНЕЦ) КАК Ч28_От,
Максимум(ВЫБОР КОГДА Р.День = 28 ТОГДА Р.До ИНАЧЕ 0 КОНЕЦ) КАК Ч28_До,
Максимум(ВЫБОР КОГДА Р.День = 28 ТОГДА Р.ЧасовНаРаботе ИНАЧЕ 0 КОНЕЦ) КАК Ч28,
Максимум(ВЫБОР КОГДА Р.День = 29 ТОГДА Р.От ИНАЧЕ 0 КОНЕЦ) КАК Ч29_От,
Максимум(ВЫБОР КОГДА Р.День = 29 ТОГДА Р.До ИНАЧЕ 0 КОНЕЦ) КАК Ч29_До,
Максимум(ВЫБОР КОГДА Р.День = 29 ТОГДА Р.ЧасовНаРаботе ИНАЧЕ 0 КОНЕЦ) КАК Ч29,
Максимум(ВЫБОР КОГДА Р.День = 30 ТОГДА Р.От ИНАЧЕ 0 КОНЕЦ) КАК Ч30_От,
Максимум(ВЫБОР КОГДА Р.День = 30 ТОГДА Р.До ИНАЧЕ 0 КОНЕЦ) КАК Ч30_До,
Максимум(ВЫБОР КОГДА Р.День = 30 ТОГДА Р.ЧасовНаРаботе ИНАЧЕ 0 КОНЕЦ) КАК Ч30,
Максимум(ВЫБОР КОГДА Р.День = 31 ТОГДА Р.От ИНАЧЕ 0 КОНЕЦ) КАК Ч31_От,
Максимум(ВЫБОР КОГДА Р.День = 31 ТОГДА Р.До ИНАЧЕ 0 КОНЕЦ) КАК Ч31_До,
Максимум(ВЫБОР КОГДА Р.День = 31 ТОГДА Р.ЧасовНаРаботе ИНАЧЕ 0 КОНЕЦ) КАК Ч31,
Р.НормаВремениЗаСмену КАК НормаВремениЗаСмену,
Сумма(Р.ЧасовНаРаботе) КАК ИтогоЗаМесяц
ИЗ
Результат КАК Р
ПРАВОЕ СОЕДИНЕНИЕ Справочник.Сотрудники КАК С
ПО С.Ссылка = Р.Сотрудник
ГДЕ
ВЫБОР
КОГДА &Сотрудник = Значение(Справочник.Сотрудники.ПустаяСсылка)
ТОГДА Истина
ИНАЧЕ С.Ссылка = &Сотрудник
КОНЕЦ
СГРУППИРОВАТЬ ПО
С.Ссылка, Р.НормаВремениЗаСмену
УПОРЯДОЧИТЬ ПО
С.Ссылка ВОЗР
АВТОУПОРЯДОЧИВАНИЕ
;
УНИЧТОЖИТЬ Результат
////////////////////////////////////////////////////////////////////////////////////////////////////
Есть массив А из элементов некоторого справочника и есть справочник Б с табличной частью из элементов того же справочника. Найти элемент Б, где список точно совпадает с массивом А (ни больше ни меньше).
ВЫБРАТЬ
Менеджеры.Ссылка
ИЗ
Справочник.Контрагенты.МенеджерыПокупателя КАК Менеджеры
ГДЕ
Менеджеры.МенеджерПокупателя В(&Массив)
СГРУППИРОВАТЬ ПО
Менеджеры.Ссылка
ИМЕЮЩИЕ
КОЛИЧЕСТВО(РАЗЛИЧНЫЕ Менеджеры.МенеджерПокупателя) = &МассивКоличество
Показать
Не работает если учитывать условие "ни больше ни меньше". Когда больше - запрос отрабатывает неверно.
Проверяю на БП 3.0 на запросе:
ВЫБРАТЬ
КонтрагентыИсторияКПП.Ссылка КАК Ссылка
ИЗ
Справочник.Контрагенты.ИсторияКПП КАК КонтрагентыИсторияКПП
ГДЕ
КонтрагентыИсторияКПП.КПП В(&МассивКПП)
СГРУППИРОВАТЬ ПО
КонтрагентыИсторияКПП.Ссылка
ИМЕЮЩИЕ
КОЛИЧЕСТВО(РАЗЛИЧНЫЕ КонтрагентыИсторияКПП.КПП) = &МассивКППКоличество
Показать
Допустим возьмём контрагента у которого КПП 3 строки: 775003035, 773601001 и 631050001
В запрос передадим массив КПП: 775003035; 773601001 и МассивКППКоличество = 2;
Запрос возвращает результат - этого контрагента, хотя у него 3 сроки!
Рабочий запрос:
ВЫБРАТЬ РАЗЛИЧНЫЕ
КонтрагентыИсторияКПП.Ссылка КАК Ссылка
ПОМЕСТИТЬ ВсеКонтрагентыСЭтимиДанными
ИЗ
Справочник.Контрагенты.ИсторияКПП КАК КонтрагентыИсторияКПП
ГДЕ
КонтрагентыИсторияКПП.КПП В(&МассивКПП)
СГРУППИРОВАТЬ ПО
КонтрагентыИсторияКПП.Ссылка
ИМЕЮЩИЕ
КОЛИЧЕСТВО(РАЗЛИЧНЫЕ КонтрагентыИсторияКПП.КПП) = &МассивКППКоличество
;
////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ РАЗЛИЧНЫЕ
КонтрагентыИсторияКПП.Ссылка КАК Ссылка
ИЗ
ВсеКонтрагентыСЭтимиДанными КАК ВсеКонтрагентыСЭтимиДанными
ВНУТРЕННЕЕ СОЕДИНЕНИЕ Справочник.Контрагенты.ИсторияКПП КАК КонтрагентыИсторияКПП
ПО ВсеКонтрагентыСЭтимиДанными.Ссылка = КонтрагентыИсторияКПП.Ссылка
СГРУППИРОВАТЬ ПО
КонтрагентыИсторияКПП.Ссылка
ИМЕЮЩИЕ
КОЛИЧЕСТВО(РАЗЛИЧНЫЕ КонтрагентыИсторияКПП.КПП) = &МассивКППКоличество
(8) Все же решил исправить по-своему. Для старых версий платформы так:
ВЫБРАТЬ
КонтрагентыИсторияКПП.Ссылка КАК Ссылка
ИЗ
Справочник.Контрагенты.ИсторияКПП КАК КонтрагентыИсторияКПП
СГРУППИРОВАТЬ ПО
КонтрагентыИсторияКПП.Ссылка
ИМЕЮЩИЕ
СУММА(ВЫБОР
КОГДА КонтрагентыИсторияКПП.КПП В (&МассивКПП)
ТОГДА 1
ИНАЧЕ 0.000001
КОНЕЦ) = &МассивКППКоличество
Показать
Для новых, где логическое выражение можно записывать сразу в поле запроса, так:
ВЫБРАТЬ
КонтрагентыИсторияКПП.Ссылка КАК Ссылка
ИЗ
Справочник.Контрагенты.ИсторияКПП КАК КонтрагентыИсторияКПП
СГРУППИРОВАТЬ ПО
КонтрагентыИсторияКПП.Ссылка
ИМЕЮЩИЕ
КОЛИЧЕСТВО(*) = &МассивКППКоличество И
МИНИМУМ(КонтрагентыИсторияКПП.КПП В (&МассивКПП)) = ИСТИНА
Показать
В числе строчек даже получился выигрыш.
Спасибо за внимательность!
72. Очистка строки от нецифровых символов
71. Определение суммарного покрытия перекрывающихся интервалов
70. Определение пересечения интервалов в кольце
69. Быстрое удаление строк в таблице значений
68. Получение интервалов неизменности курсов валют
67. Определение пропусков в последовательности чисел
66. Инвертирование периодов в запросе
65. Проверка совпадения таблиц
64. Проверка совпадения таблиц путем сравнения полного и внутреннего соединения
63. Получение списка простых чисел в запросе
62. Определение периодов работы сотрудников по данным СКУД
61. Найти документы, во всех строках которых колонка количество меньше либо равна нулю
60. Определение плановых остатков товара с учетом предшествующих фактических и будущих плановых продаж
59. Сравнение плановых и фактических дней отпуска
58. Получить дату по номеру дня недели и его порядковому номеру в месяце
57. Получение предпоследнего курса валюты
56. Определить элементарные интервалы, образующиеся при пересечении всех исходных интервалов
55. Найти количество записей, повторяющихся подряд несколько дней
54. Сравнение набора товаров, проданных сменами
53. Найти документ, состав табличной части которого соответствует параметру - таблице значений
52. Распределение товаров по ячейкам в запросе
51. Объединение пересекающихся периодов в запросе
50. Выделение разрядов числа без использования округления и деления по модулю
49. Посчитать запросом суммарную длительность различных состояний
48. Разбиение произвольного периода на интервалы в запросе
47. Поиск свободного штрихкода внутри одного префикса
46. Выбор записи по номеру из НЕПРОНУМЕРОВАННОЙ таблицы
45. Как в запросе секунды преобразовать в часы и минуты
44. Убрать префикс и лидирующие нули из номера
43. Перебор всех строковых комбинаций "0" и "1" в порядке возрастания числа единиц ("00000"->"00001"->"00010"-> ..."01011"...)
42. Транслитерация в запросе
41. Заполнение пропусков в таблице цветов
40. Количество дней недели (понедельников/вторников/...) в заданном диапазоне запросом
39. Свернуть строки в таблице значений конкатенацией
67. следующий вариант работает на порядки быстрее для больших таблиц (если не ПЕРВЫЕ 1 - выбирает все пропущенные значения и следующее по порядку):
ВЫБРАТЬ ПЕРВЫЕ 1
Т1.Х + 1
ИЗ
Дано Т1
ЛЕВОЕ СОЕДИНЕНИЕ
Дано Т2
ПО
Т2.Х = Т1.Х + 1
ГДЕ
Т2.Х Есть Null
УПОРЯДОЧИТЬ ПО
Т1.Х
З.Ы. на таблице в 1 млн. записей с индексированием по полю X (иначе какой смысл искать "дырки" в большой таблице и оставлять это поле неиндексированным) данный запрос выполняется за доли секунды в том случае как предложенный - десяток секунд.
иначе какой смысл искать "дырки" в большой таблице и оставлять это поле неиндексированным
все же бывают случаи и неиндексированных таблиц (например, если это временная таблица) и файловых баз и других СУБД, поэтому знать и уметь сравнивать разные варианты, кроме очевидных, бывает нужно.
может кому пригодится: нормализация представления числа
// Приводит переданные числовые значения Мантиссы и Порядка к нормализованной форме
// Нормализованной формой числа с плавающей запятой считается форма, когда Мантисса находится в интервале 1 ⩽ М < 10
//
// Параметры:
// ЗначениеМантисса - Число - значение числа без учёта порядка
// ЗначениеПорядок - Число - степень основания числа, на которое умножается мантисса
// НормализованнаяМантисса - Число - возвращаемое нормализованное значение мантиссы
// НормализованныйПорядок - Число - возвращаемое нормализованное значение порядка
//
Процедура НормализоватьЗначениеЧисла(ЗначениеМантисса, ЗначениеПорядок = 0, НормализованнаяМантисса = 0, НормализованныйПорядок = 0) Экспорт
Если ЗначениеМантисса = 0 Тогда
Возврат;
КонецЕсли;
Порядок = Log10(?(ЗначениеМантисса < 0, - ЗначениеМантисса, ЗначениеМантисса));
Если Порядок > 0 Тогда
Порядок = Цел(Порядок);
Иначе
Если Не Порядок = Цел(Порядок) Тогда
Порядок = Цел(Порядок) - 1;
КонецЕсли;
КонецЕсли;
НормализованныйПорядок = Порядок + ЗначениеПорядок;
НормализованнаяМантисса = ЗначениеМантисса * Pow(10, ЗначениеПорядок - НормализованныйПорядок);
КонецПроцедуры
2. Проверка наличия заполненных значений в колонке. Пустые значения в колонке должны быть одного типа, т. е., не должны встречаться вместе, например, NULL и Неопределено.
По поводу "Быстрое удаление строк в таблице значений" есть сомнение в приведенном способе.
1. Если таблица значений занимает более 100-ни Мб в ОЗУ, то получаем лишний расход ОЗУ (на 1-ю и 2-ю таблицу)
2. Если в значениях таблицы значений есть ссылочные данные, то получаем нагрузку на процессор
Вариант синтаксиса: Скопировать по отбору Описание:
Создает копию таблицы значений.
Если указан отбор, то только строки из отбора будут скопированы. Если отбор не указан, то будут скопированы все строки таблицы значений. Если указаны колонки, то только эти колонки будут скопированы. Иначе, будут скопированы все колонки таблицы значений
Наилучшим решением будет удаление по отбору по индексированной колонке
РабочаяТаблица.Индексы.Добавить("КУдалению");
найдСтр = РабочаяТаблица.НайтиСтроки(Новый Структура("КУдалению",Истина));
Для к=0 По найдСтр.ВГраница() Цикл
РабочаяТаблица.Удалить(найдСтр[к]);
КонецЦикла;
(18) Сомневаться нужно, но, чтобы сделать выводы, нужны замеры. "Лишнего" расхода ОЗУ, нагрузки на процессор (видимо, имеется ввиду работа со структурой для работы сборщика мусора). Просто сказать "наилучшим решением будет" в данном случае недостаточно. Выигрыш приема из (69) был настолько большим (в моих измерениях), что его указанные минусы не перекрывают. - Попробуйте сделать замеры сами!
Пожалуйста вот замеры, обратите на 2-ю строку, отбрасывая все лишнее, только процесс удаления и создания:
1. Удаление не вашим способом
2. Удаление вашим способом
Почему так происходит? Понимание приходит, если кодить не только в 1С, а например кодить в ООП, в Java. На самом деле при вашем способе создается НОВЫЙ объект, в который копируются данные из СТАРОГО объекта, причем при наличии ссылочных типов, идет нагрузка на процессор (можно почитать про коллекции в Java, там ясно объясняется разница между insert/delete с примитивными типами и object). Я не могу тут привести размеры ОЗУ и нагрузку на процессор (придется заморочится), но поверьте я часто работаю с большими данными и вообще я считаю наиболее оптимальным способом является удаление через запрос.
Со всем уважением к вам! Ваши статьи лаконичны и самое главное практичны!
(20) считаете вышеприведенные варианты равнозначными?
"РабочаяТаблица.Индексы.Добавить("КУдалению");" Это ничего не говорит?
А теперь провести тесты с этим кодов в обоих способах и без этого кода. Результаты изменились? Неожиданно?
будет дольше, это и так понятно. С самого начала я отметил - удаление по отбору по индексированной колонке.
А почему отказываете в индексации в другом примере? Где сказано, что в 69 обязательно не индексированная колонка?
С моей точки зрения там сказано, что при прочих равных условий будет быстрее создать новую таблицу, чем удалять строки.
Вы нашли "неравные" условия и сравниваете.
Рассматривая Ваше высказывание: "Наилучшим решением будет удаление по отбору по индексированной колонке", можно ответить:
"Быстрее всего удаляются строки путем копирования оставшихся строк по условию, обратному к условию удаления". При достаточно большой ТЗ, когда индексация начинает оказывать положительный результат, с индексацией нужной колонки Но последнее предложение должно пониматься нормальным разработчиком по-умолчанию.
РабочаяТаблица.Индексы.Добавить("КУдалению");
РабочаяТаблица = РабочаяТаблица.Скопировать(Новый Структура("КУдалению",Истина));
//найдСтр = РабочаяТаблица.НайтиСтроки(Новый Структура("КУдалению",Истина));
//Для к = 0 По найдСтр.ВГраница() Цикл
// РабочаяТаблица.Удалить(найдСтр[к]);
//КонецЦикла;
результат
и соответственно
РабочаяТаблица.Индексы.Добавить("КУдалению");
//РабочаяТаблица = РабочаяТаблица.Скопировать(Новый Структура("КУдалению",Истина));
найдСтр = РабочаяТаблица.НайтиСтроки(Новый Структура("КУдалению",Истина));
Для к = 0 По найдСтр.ВГраница() Цикл
РабочаяТаблица.Удалить(найдСтр[к]);
КонецЦикла;
Процедура ОсновныеДействияФормыЗаполнитьТЗ(Кнопка)
ТЗ.Колонки.Добавить("Номер", Новый ОписаниеТипов("Число"));
ТЗ.Колонки.Добавить("КУдалению",Новый ОписаниеТипов("Булево"));
Для к=1 По 300000 Цикл
СтрТЗ = ТЗ.Добавить();
СтрТЗ.Номер = к;
СтрТЗ.КУдалению = к%2 = 0;
КонецЦикла;
Сообщить(ТЗ.Количество());
КонецПроцедуры
Процедура ОсновныеДействияФормыАнализУдалениемСтрокТЗ(Кнопка)
ТЗКопия = ТЗ.Скопировать();
ТЗКопия.Индексы.Добавить("КУдалению");
ВремяНачала = ТекущаяУниверсальнаяДатаВМиллисекундах();
найдСтр = ТЗКопия.НайтиСтроки(Новый Структура("КУдалению",Истина));
Для к = 0 По найдСтр.ВГраница() Цикл
ТЗКопия.Удалить(найдСтр[к]);
КонецЦикла;
ВремяЗамера = ТекущаяУниверсальнаяДатаВМиллисекундах()-ВремяНачала;
Сообщить("Кол-во элементов: "+ ТЗКопия.Количество());
Сообщить("Время выполнения удалением: "+ ВремяЗамера);
КонецПроцедуры
Процедура ОсновныеДействияФормыАнализКопированиемТЗ(Кнопка)
ТЗКопия = ТЗ.Скопировать();
ТЗКопия.Индексы.Добавить("КУдалению");
ВремяНачала = ТекущаяУниверсальнаяДатаВМиллисекундах();
ТЗКопия = ТЗКопия.Скопировать(Новый Структура("КУдалению",Истина));
ВремяЗамера = ТекущаяУниверсальнаяДатаВМиллисекундах()-ВремяНачала;
Сообщить("Кол-во элементов: "+ ТЗКопия.Количество());
Сообщить("Время выполнения копированием: "+ ВремяЗамера);
КонецПроцедуры
Показать
Замеры:
300 000
Кол-во элементов: 150 000
Время выполнения удалением: 2 014
Кол-во элементов: 150 000
Время выполнения копированием: 222
Кол-во элементов: 150 000
Время выполнения удалением: 2 000
Кол-во элементов: 150 000
Время выполнения копированием: 225
Кол-во элементов: 150 000
Время выполнения удалением: 1 973
Кол-во элементов: 150 000
Время выполнения копированием: 224
Кол-во элементов: 150 000
Время выполнения удалением: 2 025
Кол-во элементов: 150 000
Время выполнения копированием: 227
Кол-во элементов: 150 000
Время выполнения удалением: 1 989
Кол-во элементов: 150 000
Время выполнения копированием: 222
Быстрее всего удаляются строки путем копирования оставшихся строк по условию, обратному к условию удаления
которое оказывается на самом деле - это:
Быстрее всего удаляются строки путем копирования оставшихся строк по условию, обратному к условию удаления". При достаточно большой ТЗ, когда индексация начинает оказывать положительный результат, с индексацией нужной колонки
Ну и конечно напоследок
Но последнее предложение должно пониматься нормальным разработчиком по-умолчанию
Я бы дописал
Нормальные разработчики - это разработчики, у которых есть телепатическая супер сила. Это шутка :)! Да, я прочитал ссылку выше к задаче 69. И все равно считаю, что удалить моим способ быстрее и самое главнее надежнее. Представьте у вас в ТЗ ярды строк, способ предложенный автором на короткое время создаст 2 копии ТЗ с 2-кратным потреблением ОЗУ (на 1-ю и 2-ю ТЗ), потом конечно 1-я удалится. Но что если у вас ОЗУ на 2 ТЗ не хватит? Получите банально "Недостаточно памяти".
Спасибо автору за интересные публикации.
Хочу поделиться своей версией минимализма для задачи 57:
ВЫБРАТЬ ПЕРВЫЕ 1
КурсыВалют.Период,
КурсыВалют.Валюта,
КурсыВалют.Курс
ИЗ
РегистрСведений.КурсыВалют КАК КурсыВалют
ВНУТРЕННЕЕ СОЕДИНЕНИЕ (ВЫБРАТЬ
МАКСИМУМ(КурсыВалют.Период) КАК Период,
&ВалютаСсылка КАК Валюта
ИЗ
РегистрСведений.КурсыВалют КАК КурсыВалют
ГДЕ
КурсыВалют.Валюта = &ВалютаСсылка) КАК МаксПериодКурсаВалюты
ПО (МаксПериодКурсаВалюты.Период > КурсыВалют.Период)
И (МаксПериодКурсаВалюты.Валюта = КурсыВалют.Валюта)
УПОРЯДОЧИТЬ ПО
КурсыВалют.Период УБЫВ
Протестировал оба варианта на таблице из 65 тысяч записей, этот вариант отрабатывает в два раза быстрее.
Вторая часть условия выполнится и из-за "или" станет истинным все условие.
Получится, что интервалы пересеклись.
Если хотите, чтобы они не пересекались, задайте значения
end = ЗаписиНаРемонт.ОкончаниеВыполнения = 8:59:59, тогда у интервалов не будет общей секунды.
(36) Неудобно отнимать секунду...
Пришлось воспользоваться этой темой (где я также и ваше решение увидел в комментах).
Заменил на
ГДЕ
(ЗаписиНаРемонт.НачалоВыполнения >= &НачальныйИнтервал
И ЗаписиНаРемонт.НачалоВыполнения < &КонечныйИнтервал
ИЛИ ЗаписиНаРемонт.ОкончаниеВыполнения <= &КонечныйИнтервал
И ЗаписиНаРемонт.ОкончаниеВыполнения > &НачальныйИнтервал
ИЛИ ЗаписиНаРемонт.НачалоВыполнения < &КонечныйИнтервал
И ЗаписиНаРемонт.ОкончаниеВыполнения > &НачальныйИнтервал
ИЛИ ЗаписиНаРемонт.НачалоВыполнения >= &НачальныйИнтервал
И ЗаписиНаРемонт.ОкончаниеВыполнения <= &КонечныйИнтервал)
Показать
из первого примера:
SET @start:=4;
SET @end:=8;
SEL ECT * FR OM `table`
WHERE
(`start` >= @start AND `start` < @end) /*смещение вперед*/
OR
(`end` <= @end AND `end` > @start) /*смещение назад*/
OR
(`start` < @end AND `end` > @start) /*вхождение - на самом деле здесь не обязательно оно обработается одним из предыдущих выражений*/
OR
(`start` >= @start AND `end` <= @end)/*поглощение и совпадение*/
Работаю над задачей определения "находится ли геоточка внутри геополигона". Вроде нашел новое решение, хотел с Вами связаться, обсудить. Пока тестирую в реальном времени. Не гуглом и не Постгри, их таинственные методы не описаны.
(44) Пробелы в номере - это уже не номер) - или должен обговариваться как исключение.
А вот пробел в префиксе (он же может быть произвольным) - это вполне нормально.
Так что я за универсальность, и против ограничений (из-за неполноты решения) на входные данные.
Перенос данных КА 1.1 => КА 2 / УТ 11 (перенос документов, начальных остатков и справочной информации из "1С:Комплексная автоматизация", ред.1.1 в "1С:Комплексная автоматизация", ред. 2.х)
Перенос данных КА 1.1 => КА 2 / УТ 11 (перенос документов, начальных остатков и справочной информации из "1С:Комплексная автоматизация", ред.1.1 в "1С:Комплексная автоматизация", ред. 2.х)