Порождающий запрос

01.11.19

Разработка - Запросы

Иногда в запросе необходимо получить искусственную таблицу заданного размера, не связанную с данными информационной базы. Эта получаемая «из воздуха» таблица может быть заполнена, например, числами натурального ряда или функционально связанными с ними значениями. Такая таблица может пригодится как временная таблица в запросе для соединения с реальными таблицами. Другой вариант – быстрое получение таблиц значений заданного размера, списков, массивов и прочее. В последних версиях MS-SQL есть возможности непроцедурной генерации таблиц посредством специального «итеративного» описания. Ну а для 1С пригодится следующее решение:

Скачать файл

ВНИМАНИЕ: Файлы из Базы знаний - это исходный код разработки. Это примеры решения задач, шаблоны, заготовки, "строительные материалы" для учетной системы. Файлы ориентированы на специалистов 1С, которые могут разобраться в коде и оптимизировать программу для запуска в базе данных. Гарантии работоспособности нет. Возврата нет. Технической поддержки нет.

Наименование По подписке [?] Купить один файл
Текст запроса
.txt 1,06Kb
73
73 Скачать (1 SM) Купить за 1 850 руб.
Текст запроса для определения частоты символов заданного текста
.txt 1,36Kb
29
29 Скачать (1 SM) Купить за 1 850 руб.
Отчет разбора текста на слова запросом
.erf 6,96Kb
33
33 Скачать (1 SM) Купить за 1 850 руб.
Текст запроса квадратного корня
.txt 0,95Kb
20
20 Скачать (1 SM) Купить за 1 850 руб.

Суть решения в том, что в пакетном запросе сначала заводится таблица с двумя строками, затем она соединяется сама с собой и число строк удваивается. Так повторяется до достижения таблицей заданного размера. Этот способ обеспечивает использование минимума соединений, от числа которых, в основном, зависит время выполнения запроса. 

Для примера приведен запрос, формирующий таблицу из чуть более миллиона строк.

ВЫБРАТЬ 0 КАК Х
ПОМЕСТИТЬ Регистр1
ОБЪЕДИНИТЬ
ВЫБРАТЬ
1
;
////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ Младшие.Х + 2 * Старшие.Х КАК Х
ПОМЕСТИТЬ Регистр2
ИЗ Регистр1 КАК Младшие, Регистр1 КАК Старшие
;
////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ Младшие.Х + 4 * Старшие.Х КАК Х
ПОМЕСТИТЬ Регистр4
ИЗ Регистр2 КАК Младшие, Регистр2 КАК Старшие
;
////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ Младшие.Х + 16 * Старшие.Х КАК Х
ПОМЕСТИТЬ Регистр8
ИЗ Регистр4 КАК Младшие, Регистр4 КАК Старшие
;
///////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ Младшие.Х + 256 * Старшие.Х КАК Х
ПОМЕСТИТЬ Регистр16
ИЗ Регистр8 КАК Младшие, Регистр8 КАК Старшие
;
////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ Младшие.Х + 65536 * Старшие.Х КАК Х
ПОМЕСТИТЬ Регистр20
ИЗ Регистр16 КАК Младшие, Регистр4 КАК Старшие

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

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

Текст и его длина передаются в запрос как параметры. Для примера считаем, что длина текста ограничена миллионом символов. Вот текст концовки этого запроса. 

 

////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ ПОДСТРОКА(&Текст, Х, 1) Символ, КОЛИЧЕСТВО(Х) КАК Частота
ИЗ Регистр20
ГДЕ Х МЕЖДУ 1 И &ДлинаТекста
СГРУППИРОВАТЬ ПО ПОДСТРОКА(&Текст, Х, 1)

Его начало такое же как на предыдущем рисунке. Интересно то, что этот метод работает быстрее, чем обработка в оперативной памяти. И сразу дает табличный результат! Например, первый мегабайт романа "Война и мир" обрабатывается в памяти 8,2 сек, а запросом - 4 секунды!

Очевидно, что запрос совсем простой. Проявив некоторую изобретательность, можно построить запрос разбора текста на слова и запросы для решения других задач обработки текста. Аналогично можно строить таблицы вхождений одно, двух, трех и т.п. символов в наименования, артикулы и пр. для ускорения подбора (вместо методов с использованием "подобно").

Определение частоты слов запросом оказалось совсем не тривиальной задачей. Вот решение:

 

////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ Младшие.Х + 256 * 256 * Средние.Х + 256 * 256 * 2 * Старшие.Х КАК Х
ПОМЕСТИТЬ Регистр21
ИЗ Регистр16 КАК Младшие, Регистр4 КАК Средние, Регистр1 КАК Старшие
;
////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ Х КАК У
ПОМЕСТИТЬ Разделители
ИЗ Регистр21
ГДЕ (НЕ ПОДСТРОКА(&Текст, Х, 1) ПОДОБНО "[а-я]") И Х МЕЖДУ 1 И &ДлинаТекста
;
////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ Х, ВЫБОР КОГДА Х = 0 ТОГДА ИСТИНА КОНЕЦ КАК Нулевой, ВЫБОР КОГДА Х > 0 ТОГДА Х КОНЕЦ КАК Длина
ПОМЕСТИТЬ Интервалы
ИЗ Регистр4
;
////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ У - Х КАК Начало, МИНИМУМ(Длина) КАК Длина
ПОМЕСТИТЬ УказателиСлов
ИЗ Разделители, Интервалы
СГРУППИРОВАТЬ ПО У - Х
ИМЕЮЩИЕ МАКСИМУМ(Нулевой) = ИСТИНА И МИНИМУМ(Длина) > 1
;
////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ ПОДСТРОКА(ПОДСТРОКА(&Текст, Начало + 1, Длина - 1), 1, 15) КАК Слово, КОЛИЧЕСТВО(Начало) КАК Частота
ИЗ УказателиСлов
СГРУППИРОВАТЬ ПО ПОДСТРОКА(ПОДСТРОКА(&Текст, Начало + 1, Длина - 1), 1, 15)

К статье прилагается файл отчета, содержащий этот запрос. С его помощью в тексте первой части "Войны и мира" была определена частота слов за 24 секунды! А это примерно 1,5 миллиона символов! Правда, если использовать "кодинг", на чистом 1С можно решить ту же задачу примерно в два раза быстрее.

В качестве неочевидного применения предложенного запроса приводится пример расчета в запросе квадратного корня от числа в диапазоне 0 - 1 048 576. Вернее, целой части этого корня.

 

////////// создается таблица с числами от 0 до 1024 ////////////////////////////
ВЫБРАТЬ 0 КАК Х ПОМЕСТИТЬ Регистр1 ОБЪЕДИНИТЬ ВЫБРАТЬ 1
;
ВЫБРАТЬ Младшие.Х + 2 * Старшие.Х КАК Х ПОМЕСТИТЬ Регистр2
ИЗ  Регистр1 КАК Младшие,   Регистр1 КАК Старшие
;
ВЫБРАТЬ Младшие.Х + 4 * Старшие.Х КАК Х ПОМЕСТИТЬ Регистр4
ИЗ  Регистр2 КАК Младшие, Регистр2 КАК Старшие
;
ВЫБРАТЬ Младшие.Х + 16 * Старшие.Х КАК Х ПОМЕСТИТЬ Регистр8
ИЗ  Регистр4 КАК Младшие, Регистр4 КАК Старшие
;
ВЫБРАТЬ Младшие.Х + 256 * Старшие.Х КАК Х ПОМЕСТИТЬ Регистр10
ИЗ  Регистр8 КАК Младшие, Регистр2 КАК Старшие
;
////////// для проверки создается таблица с различными значениями аргумента ////
ВЫБРАТЬ 123456 КАК У ПОМЕСТИТЬ Аргументы
ОБЪЕДИНИТЬ ВЫБРАТЬ 555555
ОБЪЕДИНИТЬ ВЫБРАТЬ 987654
;
////////// формируется таблица, содержащая аргумент и значение функции /////////
ВЫБРАТЬ У, МАКСИМУМ(Х) КАК Квадратный_корень_Х
ИЗ Аргументы ЛЕВОЕ СОЕДИНЕНИЕ Регистр10 ПО (Х * Х < У)
СГРУППИРОВАТЬ ПО
У

 Аналогичным или похожим путем можно рассчитать и другие обратные функции. 

Похожим приемом в запросе можно получить "таблицу хаоса" - таблицу, которая содержит случайные числа. Например, следующая функция возвращает таблицу с заданным числом строк, содержащую случайные числа, равномерно распределенные в диапазоне 0 - 1.


function ChaosTable(N, Name = "СлучайноеЧисло") export

g = new RandomNumberGenerator();

q = new Query("select &r1 as r into t1 union select &r2;

             | select &k * a.r + b.r - cast((&k * a.r + b.r) / &M - 0.5 as number(10,0)) * &M as r into t2 from t1 as a, t1 as b;

             | select &k * a.r + b.r - cast((&k * a.r + b.r) / &M - 0.5 as number(10,0)) * &M as r into t4 from t2 as a, t2 as b;

             | select &k * a.r + b.r - cast((&k * a.r + b.r) / &M - 0.5 as number(10,0)) * &M as r into t8 from t4 as a, t4 as b;

             | select &k * a.r + b.r - cast((&k * a.r + b.r) / &M - 0.5 as number(10,0)) * &M as r into t16 from t8 as a, t8 as b;

             | select top "
+ Format(N, "NG=") + "

             | (&k * a.r + b.r) / &M - cast((&k * a.r + b.r) / &M - 0.5 as number(10,0)) as "
+ Name + " from t16 as a, t4 as b");

q.SetParameter("r1", g.RandomNumber()); q.SetParameter("r2", g.RandomNumber());

q.SetParameter("k", 1664525); q.SetParameter("M", 4294967295);

return
q.Execute().Unload()

endfunction

Такая функция работает примерно в полтора раза быстрее, чем генерация случайных чисел для заполнения таблицы в цикле, а результат может использоваться прямо в запросе. В основе построения запроса лежит линейный конгруэнтный метод получения последовательности псевдослучайных чисел. Сложное выражение внутри запроса является ничем иным как нахождением остатка от деления на &M. К сожаления, непосредственно функции деления по заданному модулю в языке запросов нет.

Конечно, для использования в ответственных применениях потребуется проверка результата тестами NIST. Также было бы интересно исследовать использование для решения той же задачи метода Блюма-Блюма-Шуба. Запись запроса при этом будет еще короче.

 

Для удобства применения предложенного подхода на практике предлагается функция, которая формирует ТЕКСТ ЗАПРОСА или фрагмент пакетного запроса, выполнение которого приводит к получению временной таблицы, содержащей натуральный ряд чисел заданного размера. Вот текст этой функции


function ProtoText(N, M = 1000000000) export

    return ?(
N > 2

   
, ProtoText(M - Int(M - Sqrt(N)))

    +
strreplace(strreplace(";select top #2 a.X * #1 + b.X X into r#2 from r#1 a, r#1 b; drop r#1", "#2", format(N, "NG=")), "#1", format(M - Int(M - Sqrt(N)), "NG="))

    ,
"select 0 X into r2 union select 1")

endfunction

Функция рекурсивная, параметр M - служебный (используется для сокращения записи функции). Результирующая временная таблица имеет имя r{ЗаданныйРазмер}.

См. также

Инструментарий разработчика Роли и права Запросы СКД Программист Руководитель проекта Платформа 1С v8.3 Управляемые формы Запросы Система компоновки данных Платные (руб)

Инструменты для разработчиков 1С 8.3: Infostart Toolkit. Автоматизация и ускорение разработки на управляемых формах. Легкость работы с 1С.

15500 руб.

02.09.2020    183498    1023    403    

966

Обновление 1С Запросы Программист Платформа 1С v8.3 1С:ERP Управление предприятием 2 Абонемент ($m)

Данный инструмент помогает анализировать доработанную конфигурацию после обновления на новый релиз и находить «битые» тексты запросов, в которых участвуют несуществующие в новом релизе метаданные.

2 стартмани

06.02.2025    2134    17    XilDen    26    

36

Запросы Программист Платформа 1С v8.3 Запросы 1C:Бухгалтерия Бесплатно (free)

В статье приведена удобная возможность отладки исполняемого запроса динамического списка.

03.12.2024    5595    artemusII    11    

23

Запросы Программист Бесплатно (free)

Увидел cheatsheet по SQL и захотелось нарисовать подобное, но про запросы.

18.10.2024    13009    sergey279    18    

65

Запросы Программист Платформа 1С v8.3 Запросы 1C:Бухгалтерия Бесплатно (free)

Столкнулся с интересной ситуацией, которую хотел бы разобрать, ввиду её неочевидности. Речь пойдёт про использование функции запроса АВТОНОМЕРЗАПИСИ() и проблемы, которые могут возникнуть.

11.10.2024    8108    XilDen    36    

90

СКД Механизмы типовых конфигураций Запросы Программист Платформа 1С v8.3 1С:Зарплата и кадры государственного учреждения 3 1С:Зарплата и Управление Персоналом 3.x Россия Бесплатно (free)

Работая с типовыми отчетами в конфигурациях «Зарплата и управление персоналом, редакция 3», «Зарплата и кадры государственного учреждения, редакция 3» и подобных, в схемах компоновки данных можно встретить конструкции запросов, которые обращаются к некоторым виртуальным таблицам.

20.08.2024    3110    PROSTO-1C    0    

23

Запросы Программист Запросы Бесплатно (free)

Отлаживая взаимодействие с базой данных, мы регулярно сталкиваемся с зависающими или подозрительно долго выполняющимися обращениями, негативно влияющими на производительность. О том, как в PostgreSQL выявить подозрительные запросы, основываясь на доступной о них информации, расскажем в статье.

16.08.2024    10684    user1840182    5    

29
Комментарии
Подписаться на ответы Инфостарт бот Сортировка: Древо развёрнутое
Свернуть все
0. ildarovich 7956 15.09.11 02:40 Сейчас в теме
Иногда в запросе необходимо получить искусственную таблицу заданного размера, не связанную с данными информационной базы. Эта получаемая «из воздуха» таблица может быть заполнена, например, числами натурального ряда или функционально связанными с ними значениями. Такая таблица может пригодится как временная таблица в запросе для соединения с реальными таблицами. Другой вариант – быстрое получение таблиц значений заданного размера, списков, массивов и прочее. В последних версиях MS-SQL есть возможности непроцедурной генерации таблиц посредством специального «итеративного» описания. Ну а для 1С пригодится следующее решение:


Перейти к публикации

1. O-Planet 6403 15.09.11 02:40 Сейчас в теме
Впечатлила аватарка. Уже сразу решил плюсануть, не читая. Но почитал. Задача такая возникала. Про таблицу с битами не додумался тогда. Зачет.
2. PlatonStepan 38 15.09.11 03:52 Сейчас в теме
это очень сильное колдунство! :)
3000чертей!
повторил запрос, 1с-серв всю память сьел и подавился, а предприятие зависло... предупреждать надо!! :(((
кстати, для создания ТЗ определённого размера можно использовать COMSafeArray
acanta; wowik; orfos; WKBAPKA; sleakers; palsergeich; адуырщдв; cool.vlad4; ildarovich; support; +10 Ответить
6. ildarovich 7956 15.09.11 11:55 Сейчас в теме
(2) Видимо, было мало оперативки, в таком случае ожидаемы и проблемы с формированием ТЗ из миллиона строк.
Важен принцип, а конкретный запрос приведен для примера и оценки скорости (замеры делались на ноутбуке в файловом варианте базы).
По аналогии можно формировать и меньшие таблицы.
Если их размер не равен степеням двойки, используем условие ГДЕ X < &ЗаданныйРазмер.
За напоминание о COMSafeArray спасибо!
(4) Запрос из http://infostart.ru/public/68269/ я видел,
хотя за основу брал свое же решение из http://forum.infostart.ru/forum14/topic35991/message400742/#message400742 (внешнего сходства немного, но общая "математика").
Отличие от http://infostart.ru/public/68269/ я вижу в том, что:
1) оно нацелено не только на даты (кроме того, что уже сказано, например, на основе этого запроса можно подбором находить обратные функции, не вычисляемые в запросе, типа квадратного корня и прочих);
2) оптимизировано по времени выполнения за счет соединения таблицы с собой (различные варианты сравнивались).
(5) Цикл из миллиона повторений сразу сделает этот прием неконкурентоспособным, а вот если все время удваивать подстроку - может и получиться...
10. cool.vlad4 2 15.09.11 17:39 Сейчас в теме
(6)
Цикл из миллиона повторений сразу сделает этот прием неконкурентоспособным, а вот если все время удваивать подстроку - может и получиться..
А там можно Формат использовать, для получения строки
3. IgorI 15.09.11 10:17 Сейчас в теме
Хоть идея и совершенно простая, но реализовать это в запросе... Спасибо за наводку!
15. IgorI 16.09.11 10:18 Сейчас в теме
(4) А я и не предполагал, что это что-то уникальное. Но вот попалась на глаза именно эта статья.
А Вам спасибо за "подборку" тематических статей. Обязательно посмотрю.
5. i132 123 15.09.11 10:56 Сейчас в теме
Если создавать таблицу занчений с одинаковыми строками, можно поигратьса со ЗначениемИзСтрокиВнутр(),
Например Сохранить в строку таблицу значений с одной строкой а потом в цикле вставлять перед окончанием эту строку...
9. cool.vlad4 2 15.09.11 17:38 Сейчас в теме
(5) Ага, я также и массив заполняю, изменяю.(0) +++ :D
7. Oleg_nsk 280 15.09.11 13:23 Сейчас в теме
Я подобное так делал:

Запрос.Текст = "ВЫБРАТЬ
	|	0 КАК Бит
	|ПОМЕСТИТЬ Регистр
	|
	|ОБЪЕДИНИТЬ ВСЕ
	|
	|ВЫБРАТЬ
	|	1
	|;
	|
	|////////////////////////////////////////////////////////////­////////////////////
	|ВЫБРАТЬ
	|	Н10.Бит + 2 * Н9.Бит + 4 * Н8.Бит + 8 * Н7.Бит + 16 * Н6.Бит + 32 * Н5.Бит + 64 * Н4.Бит + 128 * Н3.Бит + 256 * Н2.Бит + 512 * Н1.Бит + 1024 * Н0.Бит + 2048 * Н11.Бит КАК Сумма
	|ИЗ
	|	Регистр КАК Н11,
	|	Регистр КАК Н10,
	|	Регистр КАК Н9,
	|	Регистр КАК Н8,
	|	Регистр КАК Н7,
	|	Регистр КАК Н6,
	|	Регистр КАК Н5,
	|	Регистр КАК Н4,
	|	Регистр КАК Н3,
	|	Регистр КАК Н2,
	|	Регистр КАК Н1,
	|	Регистр КАК Н0"
Показать
8. ildarovich 7956 15.09.11 13:57 Сейчас в теме
(7) Проверял, работает медленнее, кроме того, удобнее писать

Н10.Бит + 2 *(Н9.Бит + 2 * (Н8.Бит + 2 * (Н7.Бит + 2 * (Н6.Бит + 2 * (Н5.Бит + 2 * (Н4.Бит + 2 * (Н3.Бит + 2 * ( Н2.Бит + 2 * (Н1.Бит + 2 * (Н0.Бит + 2 * Н11.Бит)))))))))) 
uncle_Vasya; +1 Ответить
38. alexk-is 6546 22.09.11 11:08 Сейчас в теме
Потестировал немного.
Получил следующие результаты.

Запросы типа (7), (17), (19) проигрывают (0) в файловом варианте как на 8.1, так и на 8.2.
А вот в SQL варианте они работают быстрее как на 8.1, так и на 8.2. MS SQL 2005 Standart.

Возможно, что на других SQL серверах будут другие результаты.

Запрос, который участвовал в тестировании:

выбрать 0 как х поместить х0 объединить все выбрать 1
объединить все выбрать 2 объединить все выбрать 3 объединить все выбрать 4
объединить все выбрать 5 объединить все выбрать 6 объединить все выбрать 7
объединить все выбрать 8 объединить все выбрать 9
;
выбрать х1.х + х2.х * 10 + х3.х * 100 + х4.х * 1000 + х5.х * 10000 + х6.х * 100000 как х
из х0 как х1, х0 как х2, х0 как х3, х0 как х4, х0 как х5, х0 как х6
40. ildarovich 7956 22.09.11 13:43 Сейчас в теме
(38) Очень интересно! - Если можете, приведите численные результаты замеров для SQL.

Потом, возможно, стоит посмотреть:

0) результаты для (7) и (19), то есть с использованием основания 2;
1) диапазоны до 65536 и более миллиона;
2) вариант с (0), когда начальная таблица - это Регистр4 (выбрать 0 - 15 поместить регистр4).

Это для того, чтобы понять, что влияет больше: число соединений (у (0) и (38) оно одинаково! и, думаю, это главное) или время трансляции запроса в SQL или необходимость фиксации временных таблиц.
Тогда и можно будет сделать выводы о сравнительной применимости (0) и (38) как подходов к формированию искусственных таблиц.
41. alexk-is 6546 22.09.11 14:18 Сейчас в теме
(40) Время замеров в секундах. Результат запросов 1000000 записей.
Платформы 8.1.15.14 и 8.2.14.533.

(0)
    8.1   8.2
Ф   2.4   1.3
С   3.4   2.1


(38)
    8.1   8.2
Ф   3.8   2.0
С   2.9   1.9


(0) + оптимизация
    8.1   8.2
Ф   1.9   1.2
С   3.1   2.1


(38) + оптимизация
    8.1   8.2
Ф   2.9   1.9
С   2.7   1.7
serg1983; Redokov; ildarovich; +3 Ответить
42. ildarovich 7956 22.09.11 14:56 Сейчас в теме
(41) Большое спасибо! - А что такое "+ оптимизация"?

Также уточню гипотезу из (40): Кажется, что подход (38) выигрывает у подхода (0) только в узком диапазоне условий, когда число соединений в запросах получается одинаковым. Под подходами я имел ввиду формирование искусственной таблицы любого заданного размера "взрывным" способом "порождающего запроса" (0), либо линейно-нарастающим числом соединений как в (38).
43. alexk-is 6546 22.09.11 16:37 Сейчас в теме
(42) Ничего особенного. Поправил запрос, чтобы при тех же результатах он работал быстрее.
11. Famza 85 15.09.11 23:34 Сейчас в теме
Любопытно...А в каком практическом решении такое использовалось? :-)
12. dkprim 5 16.09.11 08:59 Сейчас в теме
13. dkprim 5 16.09.11 09:00 Сейчас в теме
(11)присоединяюсь :)
а вообще, понравилась идея и реализация. всегда нравится разбираться с такими задачами. интересно и занятно :)
спасибо за предоставленное решение :)
16. ildarovich 7956 16.09.11 10:24 Сейчас в теме
(11) Если Ваш вопрос к тому, что не хватает нескольких не абстрактных, а "приземленных" примеров использования, то я постараюсь привести еще несколько. Все же посмотрите внимательно на пример про извлечение квадратного корня. Как иначе вычислить расстояние в запросе? (вообще то есть еще один способ - быстрый, но не такой компактный).

(14) Видимо, Вы что-то пропустили. Речь как раз идет о
создали какую надо таблицу
. Решается именно проблема быстрого создания (из ничего) какой надо таблицы, а не передачи ее в запрос. Таблица может создаваться в другом запросе и передаваться в текущий через менеджер - суть не в этом, а в том, как быстро изначально создать таблицу.
22. ildarovich 7956 17.09.11 14:15 Сейчас в теме
(11) (12) Добавил пример использования предложенного подхода в задачах обработки текста - показал, как можно одним запросом очень быстро получить частоту символов заданного текста.
91. erazh 21.05.20 19:56 Сейчас в теме
(11)Использовал в СКД. Нужно было применить функцию СокрЛП() к входному набору данных, в котором есть поля, где пользователь вводил сам данные. Отчет давал неверные данные, т.к. пользователь добавлял пробелы перед данными и после них. Иногда таких пробелов было несколько. В частности, это РС "ДокументыФизическихЛиц"(Номер, Серия) одного из продуктов Аудит-Эскорта.
14. Unstappoble 16.09.11 09:36 Сейчас в теме
ухаха))) бред) для этого придумали менеджер временных таблиц, создали какую надо таблицу и используйте
17. Angeros 16.09.11 11:28 Сейчас в теме
Ну и что... есть почти уже стандартный запрос для получения последовательности дат. А в чем у вас свежесть идеи???


ВЫБРАТЬ
	0 КАК Цифра
ПОМЕСТИТЬ ВсеЦифры

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

ВЫБРАТЬ
	1

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

ВЫБРАТЬ
	2

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

ВЫБРАТЬ
	3

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

ВЫБРАТЬ
	4

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

ВЫБРАТЬ
	5

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

ВЫБРАТЬ
	6

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

ВЫБРАТЬ
	7

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

ВЫБРАТЬ
	8

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

ВЫБРАТЬ
	9
;

////////////////////////////////////////////////////////////­////////////////////
ВЫБРАТЬ
	ДОБАВИТЬКДАТЕ(&ДатаНач, ДЕНЬ, ВсеЦифры4.Цифра * 1000 + ВсеЦифры3.Цифра * 100 + ВсеЦифры2.Цифра * 10 + ВсеЦифры1.Цифра * 1) КАК ДатаДень
ПОМЕСТИТЬ ВсеДни
ИЗ
	ВсеЦифры КАК ВсеЦифры1
		ВНУТРЕННЕЕ СОЕДИНЕНИЕ ВсеЦифры КАК ВсеЦифры2
		ПО (ВсеЦифры2.Цифра * 10 + ВсеЦифры1.Цифра * 1 <= РАЗНОСТЬДАТ(&ДатаНач, КОНЕЦПЕРИОДА(&ДатаКон, ДЕНЬ), ДЕНЬ))
		ВНУТРЕННЕЕ СОЕДИНЕНИЕ ВсеЦифры КАК ВсеЦифры3
		ПО (ВсеЦифры3.Цифра * 100 + ВсеЦифры2.Цифра * 10 + ВсеЦифры1.Цифра * 1 <= РАЗНОСТЬДАТ(&ДатаНач, КОНЕЦПЕРИОДА(&ДатаКон, ДЕНЬ), ДЕНЬ))
		ВНУТРЕННЕЕ СОЕДИНЕНИЕ ВсеЦифры КАК ВсеЦифры4
		ПО (ВсеЦифры4.Цифра * 1000 + ВсеЦифры3.Цифра * 100 + ВсеЦифры2.Цифра * 10 + ВсеЦифры1.Цифра * 1 <= РАЗНОСТЬДАТ(&ДатаНач, КОНЕЦПЕРИОДА(&ДатаКон, ДЕНЬ), ДЕНЬ))
Показать
18. ildarovich 7956 16.09.11 12:38 Сейчас в теме
В (17) и (7) делается примерно одно и то же. Создается исходная таблица из 10-ти или 2-х строк и во вторм запросе пакета производится 2 или 9 соединений для получения таблицы из 1000 строк.

"Первая свежесть" идеи (0) в том, чтобы минимизировать число соединений на всех этапах получения искусственной таблицы любого заданного размера и, таким образом, ускорить ее построение. Для этого обеспечивается квадратичный рост размера получаемой таблицы 2 - 4 - 16 - 256 - 65536 - ... На каждом этапе размер возводится в квадрат за одно соединение. Это похожий, но другой, более быстрый принцип (проверял, сравнивал)!
Во-вторых, я предлагаю использовать получаемые таблицы не только для генерации дат в заданном диапазоне, но и для быстрого (проверено!) формирования больших таблиц значений, массивов, списков; для вычисления обратных функций, которых нет в языке запросов; для решения других задач, примеры которых я еще приведу. То есть "вторая свежесть идеи" заключается в обобщении подхода с использованием искусственно-порожденных таблиц, в использовании его для решения других задач.
81. skyadmin 61 29.01.16 12:55 Сейчас в теме
(17) Angeros, Не проще ли в цикле заполнить таблицу дат и передать ее в запрос?
82. ildarovich 7956 29.01.16 13:31 Сейчас в теме
(81) skyadmin, то, что вы предлагаете реально сложнее и дольше по времени. "Я этого еще не знаю и не умею" не равно "сложнее".
cleaner_it; +1 Ответить
19. Fragster 1154 16.09.11 13:11 Сейчас в теме
Делал подобное через таблицу из чисел от 0 до 9 и соединением ее самой с собой с множителем "10" несколько раз (кстати, последоватеьлное соединеине не нужно, можно все в одном:

ВЫБРАТЬ
	0 КАК б
ПОМЕСТИТЬ Т

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

ВЫБРАТЬ
	1
;

////////////////////////////////////////////////////////////­////////////////////
ВЫБРАТЬ
	Т0.б + 2 * Т1.б + 4 * Т2.б + 8 * Т3.б + 16 * Т4.б + 32 * Т5.б + 64 * Т6.б + 128 * Т7.б КАК Числа
ИЗ
	Т КАК Т0,
	Т КАК Т1,
	Т КАК Т2,
	Т КАК Т3,
	Т КАК Т4,
	Т КАК Т5,
	Т КАК Т6,
	Т КАК Т7

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


)
20. ildarovich 7956 16.09.11 14:44 Сейчас в теме
(19) Это такое же по сути решение, как в (7) и (17). Я предлагаю другое решение, потому что метод "все в одном" работает медленнее (проверял, пробовал)! У него ("все в одном") больше соединений! В этом вся суть!
В Вашем варианте для получения таблицы из миллиона записей потребуется 19 соединений (число волшебно совпадает с номером Вашего поста), а в моем - 5! 19 и 5 - есть разница? То есть это не просто разная запись, это другой принцип. И, как вижу, все же не очевидный, поскольку столько людей не увидели разницы.
Кстати, в моем варианте (19) используется запись, не требующая знания ряда степеней двойки:
Т0.б + 2 * (Т1.б + 2 * (Т2.б + 2 * (Т3.б + 2 * (Т4.б + 2 * (Т5.б + 2 * (Т6.б + 2 * Т7.б)))))).
Извините, что вынужден повторятся. Вижу, что предыдущие комментарии не читаются.
21. sinichkas 16.09.11 16:47 Сейчас в теме
очень удобная весч,спасибо
23. dimanich70 896 17.09.11 15:38 Сейчас в теме
Побольше бы примеров, как это можно использовать в повседневной работе. А так за не тривиальность плюсую. Раньше про такой метод не читал.
24. sound 538 17.09.11 15:51 Сейчас в теме
25. hogik 444 18.09.11 21:19 Сейчас в теме
(0)
"Например, первый мегабайт романа "Война и мир" обрабатывается в памяти 8,2 сек, а запросом - 4 секунды!"©
Сергей.
И это не "запрос" молодец, а интерпретатор/компилятор 1С-а бяка. ;-)
Проверил алгоритм в памяти на "1С 7.7".
Если исходные данные в строке - 1249 сек.
Если данные в массиве - 2 сек.
Ну, а перегон из строки в массив занял 1215 сек.
Любопытно, что строка в 100000 символов обрабатывается за 12 сек.
А на С++ алгоритм выполняется - 0,00253 сек.
29. ildarovich 7956 18.09.11 21:59 Сейчас в теме
(25) Конечно, это так. Все, что можно сделать одной инструкцией, 1С делает гораздо быстрее. И тут фактически мы заставляем выполнить (через запрос и язык запросов) некоторые сложные действия одной инструкцией Запрос.Выполнить(). Получается быстрее. Это стандартный прем оптимизации - найти одну инструкцию.
Правда, меня удивляют приведенные Вами данные. Разбор строки (определение частот) из миллиона символов в оперативной памяти занимает в 8-ке 8,2 секунды (использовал соответствия, запись в одну строку, отключенный отладчик). Неужели 7-ка настолько медленнее? Как-то не верится.
31. hogik 444 18.09.11 22:17 Сейчас в теме
(29)
"Неужели 7-ка настолько медленнее? Как-то не верится."(с)
Сергей.
Я тщательно проверял свой текст алгоритма. ;-)
Думаю, время со строкой в 1000000 - это, типа, глюк.
Скорости для строк:
1 000 000 байт - 1249 сек.
100 000 байт - 12 сек.
10 000 байт - 0.157 сек.
1 000 байт - 0.005 сек.
И, вообще, в семерке много подобных "странностей"... :-)
33. hogik 444 19.09.11 19:31 Сейчас в теме
(29)
Сергей.
Я напоминаю себе, возней с "семеркой", персонажа:
"Неуловимый Джо — персонаж известного анекдота; обозначает человека или явление, всем известного, но при этом никому не нужного."(с)
Я выяснил. :-)
В "семерке" время выполнения функции Сред(Строка,Позиция,1) линейно зависит от длины исходной строки (первого аргумента). Т.е. эта функция, как бы принимает не адрес строки, а - значение. Блеск... :-) Интересно, а как в "восьмерке" работает такая функция?
34. ildarovich 7956 19.09.11 23:45 Сейчас в теме
(33) В восьмерке эта функция работает достаточно быстро. Вот такой цикл
Цикл Для ё = 1 По 1048576 Цикл ж = Сред(Текст, ё, 1); Частота[ж] = ?(Частота[ж] = Неопределено, 0, Частота[ж] + 1) КонецЦикла

выполняется 8,2 секунды, а в нем есть еще чтение и запись соответствия.
Про трудности работы с длинными строками в 77 говорилось в одной из здешних публикаций по оптимизации кода в 77. Там предлагалось разбивать строки перед обработкой.
35. hogik 444 20.09.11 00:27 Сейчас в теме
(34)
Сергей.
Рекомендации, типа, разбить строки - интересно. :-)
А разбивать строки - функцией Сред(), как это у меня сделано, например, в массив? ;-)
Времена см. в (25) сообщении. Суммарное время выполнения останется прежним. Нет - это не выход. Печально, еще и то, что если написать подобные функции на ВК, то очень большие накладные расходы на вызов методов. Например, метод Х=Lib.DeleteStr("*",1,1) для 100000 вызовов выполняется 160 секунд. А этот метод, всего, что и делает - из строки в один байт удаляет первый символ и возвращает строку нулевой длины. Еще смешней. Время просмотра таблицы в 2700000 циклом - 30 секунд. Но, если в этом цикле выполнять присвоение полей таблицы в рабочие переменные (15 штук, средняя длина поля - 10 байт), то время становится - 140 секунд. А ведь все поля, после чтения записи, уже лежат в оперативной памяти. Вот такая жесть в "семерке"... :-( Я давно пишу "боевые" куски алгоритмов на С++ с минимальным количеством вызовов методов ВК. Т.е. "максимально-целиком" загоняю алгоритм в С++.
Вот... (с)
26. Поручик 4673 18.09.11 21:36 Сейчас в теме
(0) А нельзя ли текст запросов текстом публиковать, а не рисунками.
27. ildarovich 7956 18.09.11 21:49 Сейчас в теме
(26) Тексты запросов в файлах, прилагаемых к публикации.
Я пробовал "разукрашивать" тексты, но у меня потом форматирование разъезжается, решил, что рисунки проще.
28. Поручик 4673 18.09.11 21:52 Сейчас в теме
(27) Разукрашивал этим http://infostart.ru/public/19856/ ? Люди пользуются, ничего не разъезжается.
30. ildarovich 7956 18.09.11 22:00 Сейчас в теме
32. onyx 29 19.09.11 05:25 Сейчас в теме
Понравилась идея и реализация. всегда нравится разбираться с такими задачами. интересно и занятно :)
спасибо за предоставленное решение :)
36. jjinn 21.09.11 10:29 Сейчас в теме
37. zhleonid8 21.09.11 14:46 Сейчас в теме
39. vec435 17 22.09.11 13:38 Сейчас в теме
44. ildarovich 7956 10.10.11 20:41 Сейчас в теме
Добавлен пример запроса, разбивающего текст на слова и определяющего частоту слов текста. Для обработки 1,5 миллиона символов текста романа "Война и мир" запросом понадобилось 24 секунды!
45. alexk-is 6546 11.10.11 00:48 Сейчас в теме
(0) Код картинками - ну, это со зла, со зла...
46. ildarovich 7956 11.10.11 08:46 Сейчас в теме
(45) Уже обещал - переделаю в ближайшее время.
47. ildarovich 7956 15.10.11 01:33 Сейчас в теме
(45)(46) Переделал тексты запросов из картинок в раскрашенный текст
48. qwerty_3 18.11.11 21:32 Сейчас в теме
Очень интересно, спасибо.
49. пользователь 06.12.11 12:24
Сообщение было скрыто модератором.
...
50. logos 216 24.09.12 00:26 Сейчас в теме
Огромное спасибо за полезную информацию
51. ildarovich 7956 21.11.12 15:04 Сейчас в теме
Добавил пример получения в запросе "таблицы хаоса" - таблицы, которая содержит случайные числа
52. andrewks 1378 21.11.12 16:28 Сейчас в теме
(51)
Сложное выражение внутри запроса является ничем иным как нахождением остатка от деления на &M

RandomNumber(), как известно, может вернуть 0. и вот если так случится, что и в r1, и в r2 придут нули - тогда ой. конструкция &N-cast(&N/&M-0.5 as number(10,0))*&M даст при N = 0 не N % M, а -M
чтобы не городить case внутри запроса, думаю, проще "поднять" нижнюю границу через вызов RandomNumber(1)
53. ildarovich 7956 21.11.12 19:33 Сейчас в теме
(52) Спасибо! - Вы очень внимательны. Согласен. Хотя вероятность такого события и составляет 1 / (4294967295 * 4294967295), то есть меньше одной квинтиллионной, но подстраховаться предложенным Вами способом ничего не стоит, я сделаю это, когда в очередной раз буду обновлять статью.
54. ildarovich 7956 07.12.12 23:50 Сейчас в теме
Добавил функцию, формирующую ТЕКСТ ЗАПРОСА (может быть фрагментом пакетного запроса), формирующего искусственную таблицу заданного размера. Это должно быть очень практично: теперь не нужно заранее знать 31, 365 или больше дат (например) нужно получить в таблице - функция сформирует фрагмент запроса для любого заданного количества строк искусственной таблицы. Способ в целом тот же, но немного упрощен: например, таблица из 1000 строк получается перемножением таблиц из 34 строк, таблица из 34 строк - перемножением таблиц из 6 строк, таблица из 6 строк - перемножением таблиц из 3 строк, а она - перемножением таблиц из двух строк. То есть каждый раз вычисляется квадратный корень и ближайшее целое сверху к этому корню число - это и есть размер умножаемой таблицы.
55. catena 110 12.12.12 12:49 Сейчас в теме
У вас подсчет частоты слов пропускает первое слово, если строка начинается не с пробела или другого символа. Надо в разделители добавить 0.
А так с интересом прочитала. В третий раз, как оказалось :)
ildarovich; +1 Ответить
56. ildarovich 7956 12.12.12 14:02 Сейчас в теме
(55) Спасибо! Вы очень внимательны. Чтобы первое слово не пропускалось, к таблице разделителей нужно добавить строку, содержащую 0. В результате этот фрагмент запроса будет выглядеть так:
ВЫБРАТЬ Х КАК У
ПОМЕСТИТЬ Разделители
ИЗ Регистр21
ГДЕ (НЕ ПОДСТРОКА(&Текст, Х, 1) ПОДОБНО "[а-я]") И Х МЕЖДУ 1 И &ДлинаТекста ИЛИ Регистр21.Х = 0
;
При очередном обновлении поправлю в статье. Приятно вести обсуждение на уровне сути вопроса. А то иногда кажется, что в содержательной части некоторых статей никто разбираться и не старается. А так я бы добавил, что основной хитростью данного запроса является ограничение длины слов (в примере взято ограничение 16 знаков, хотя можно и больше). Именно это позволяет уйти от квадратичной зависимости времени работы запроса от длины текста.
57. catena 110 12.12.12 14:11 Сейчас в теме
(56)Я просто люблю играться с запросами и всегда разбираю, если нахожу что-то интересное. Сохраняя этот запрос из консоли, увидела, что он у меня уже сохранен, да и плюс я оказывается уже ставила :)
58. Al-X 20.06.13 13:13 Сейчас в теме
Спасибо за предоставленные алгоритмы! Убраю их в свою коллекцию....
59. Synoecium 787 26.08.13 11:56 Сейчас в теме
По поводу алгоритма Блюм-Блюм-Шуба (BBS), автор по-видимому имеет ввиду подобный следующему запрос получения последовательности СЧ:
ВЫБРАТЬ
    &x01 КАК x
ПОМЕСТИТЬ t1

ОБЪЕДИНИТЬ

ВЫБРАТЬ
    &x02
;

////////////////////////////////////////////////////////////­////////////////////
ВЫБРАТЬ
    (a.x + 2 * b.x) * (a.x + 2 * b.x) - (ВЫРАЗИТЬ((a.x + 2 * b.x) * (a.x + 2 * b.x) / &M - 0.5 КАК ЧИСЛО(10, 0))) * &M КАК x
ПОМЕСТИТЬ t2
ИЗ
    t1 КАК a,
    t1 КАК b
;

////////////////////////////////////////////////////////////­////////////////////
ВЫБРАТЬ
    (a.x + 2 * b.x) * (a.x + 2 * b.x) - (ВЫРАЗИТЬ((a.x + 2 * b.x) * (a.x + 2 * b.x) / &M - 0.5 КАК ЧИСЛО(10, 0))) * &M КАК x
ПОМЕСТИТЬ t4
ИЗ
    t2 КАК a,
    t2 КАК b
;

////////////////////////////////////////////////////////////­////////////////////
ВЫБРАТЬ
    (a.x + 2 * b.x) * (a.x + 2 * b.x) - (ВЫРАЗИТЬ((a.x + 2 * b.x) * (a.x + 2 * b.x) / &M - 0.5 КАК ЧИСЛО(10, 0))) * &M КАК x
ПОМЕСТИТЬ t8
ИЗ
    t4 КАК a,
    t4 КАК b
;

////////////////////////////////////////////////////////////­////////////////////
ВЫБРАТЬ
    (a.x + 2 * b.x) * (a.x + 2 * b.x) - (ВЫРАЗИТЬ((a.x + 2 * b.x) * (a.x + 2 * b.x) / &M - 0.5 КАК ЧИСЛО(10, 0))) * &M КАК x
ПОМЕСТИТЬ t16
ИЗ
    t8 КАК a,
    t8 КАК b
;

////////////////////////////////////////////////////////////­////////////////////
ВЫБРАТЬ ПЕРВЫЕ 100
    (a.x + 2 * b.x) * (a.x + 2 * b.x) / &M - (ВЫРАЗИТЬ((a.x + 2 * b.x) * (a.x + 2 * b.x) / &M - 0.5 КАК ЧИСЛО(10, 0))) КАК Результат
ИЗ
    t16 КАК a,
    t4 КАК b
Показать
60. ildarovich 7956 26.08.13 13:30 Сейчас в теме
(59) Спасибо за проявленный интерес к данной теме. Для меня применение BBS осталось на уровне идеи - я ее не проверял - тогда казалось, что данный алгоритм даст более компактные выражениям в запросе. Однако были сомнения по поводу симметричности алгоритма - не приведет ли это к очевидной зависимости элементов в последовательности? В любом случае результат нужно тестировать специальными тестами. Запрос, приведенный в статье, дает в исходном виде не очень хорошие результаты. Поэтому на практике следует еще выбирать из полученных чисел только младшие разряды.
61. Synoecium 787 26.08.13 15:15 Сейчас в теме
(60) я тоже сомневаюсь в качестве такой генерации, но такие же сомнения возникают по поводу вашего примера с линейным конгруэнтным методом. Там ведь также расходятся цепочки зависимостей от пар a,a;a,b;b,a;b,b. Сам алгоритм я делал как-то на с++, там это делается довольно просто и качество генерации высокое, поэтому стало интересно, как вы это представляете на языке запросов :)
62. ildarovich 7956 26.08.13 17:31 Сейчас в теме
(61) Вообще генерация случайных чисел - слишком большая тема, чтобы ее касаться так просто и мимоходом. Можно вспомнить и главы из "Исскуство программирования" Дональда Кнута и ERNIE 1 из лондонского музея науки. Данный запрос я написал под впечатлением от Keccak. Из его описания я понял, что еще есть место для проб и ошибок в данной области. Это - проба, а насколько это ошибка покажут практика и тесты.
Прикрепленные файлы:
63. Synoecium 787 26.08.13 17:37 Сейчас в теме
Прошу меня извинить, но уж очень тема интересная :)
Накидал запрос, который из находит значения корней из заданной таблицы аргументов. При x <= 1 млн, точность 3 знака после запятой. Работает довольно шустро, на ноутбуке 1000 значений считает за 0.2 сек:

ВЫБРАТЬ
	&x
ПОМЕСТИТЬ источник
;

////////////////////////////////////////////////////////////­////////////////////
ВЫБРАТЬ
	источник.x / 2 КАК а,
	источник.x
ПОМЕСТИТЬ т1
ИЗ
	источник КАК источник
;

////////////////////////////////////////////////////////////­////////////////////
ВЫБРАТЬ
	(((т1.а + т1.x / т1.а) / 2 + т1.x / ((т1.а + т1.x / т1.а) / 2))/2 + x/(((т1.а + т1.x / т1.а) / 2 + т1.x / ((т1.а + т1.x / т1.а) / 2))/2))/2 КАК а,
	т1.x
ПОМЕСТИТЬ т2
ИЗ
	т1 КАК т1
;

////////////////////////////////////////////////////////////­////////////////////
ВЫБРАТЬ
	(((т2.а + т2.x / т2.а) / 2 + т2.x / ((т2.а + т2.x / т2.а) / 2))/2 +x/(((т2.а + т2.x / т2.а) / 2 + т2.x / ((т2.а + т2.x / т2.а) / 2))/2))/2 КАК а,
	т2.x
ПОМЕСТИТЬ т3
ИЗ
	т2 КАК т2
;

////////////////////////////////////////////////////////////­////////////////////
ВЫБРАТЬ
	(((т3.а + т3.x / т3.а) / 2 + т3.x / ((т3.а + т3.x / т3.а) / 2))/2 +x/(((т3.а + т3.x / т3.а) / 2 + т3.x / ((т3.а + т3.x / т3.а) / 2))/2))/2 КАК а,
	т3.x
ПОМЕСТИТЬ т4
ИЗ
	т3 КАК т3
;

////////////////////////////////////////////////////////////­////////////////////
ВЫБРАТЬ
	(((т4.а + т4.x / т4.а) / 2 + т4.x / ((т4.а + т4.x / т4.а) / 2))/2 + x/(((т4.а + т4.x / т4.а) / 2 + т4.x / ((т4.а + т4.x / т4.а) / 2))/2))/2 КАК а,
	т4.x
ПОМЕСТИТЬ т5
ИЗ
	т4 КАК т4
Показать
Ёпрст; ildarovich; +2 Ответить
64. ildarovich 7956 26.08.13 18:03 Сейчас в теме
(63) Все правильно. Формула Герона. Мне пришлось применить ее в обработке к статье "Как нарисовать граф на 1С". Там вышло очень удачно, что итерации по уточнению корня можно делать ПАРАЛЛЕЛЬНО с работой основного алгоритма расчета перемещений. Поэтому хватило простой формулы (а + б/а)/2. До того, как я до этого додумался, приходилось, как и Вам, подставлять результаты итераций друг в друга. Но мне хватало трех итераций, поскольку в качестве начального приближения я брал сумму катетов. Так как задача была конкретная - рассчитать гипотенузу. Максимальная погрешность при таком подходе была 0,197 процента. За три итерации! Поэтому могу предложить в дополнение к Вашему безусловно правильному подходу, еще исходя из характера задачи выбирать начальное приближение. Тогда можно сэкономить итерации. Также в плане обмена опытом могу сказать, что при упрощении получающихся громоздких выражений полезно пользоваться сайтом http://www.wolframalpha.com/. Ну а подход, показанный в данной статье, конечно не быстрый, но зато универсальный.
65. Synoecium 787 27.08.13 07:27 Сейчас в теме
(64) под формулой Герона вы наверное имеете ввиду формулу вида y=(c^2+a^2-b^2)/2c, но что-то не улавливаю связи между ней и вычислением корня числа. А вообще в моем запросе используется частный случай метода Ньютона (еще известный как метод касательных Ньютона-Рафсона)
x_(n+1)=x_(n)-f(x)/f'(x)
в случае квадратного корня: x_(n+1)=0.5(x_(n)+N/x_(n)), полагаем что f(x)=x^2-N
66. ildarovich 7956 27.08.13 09:28 Сейчас в теме
(65) Я имел ввиду 'http://en.wikipedia.org/wiki/Methods_of_computing_square_roots'
. В русской википедии тоже есть статья, но ссылку на нее не могу вставить, так как подчеркивание в названии обрезает ссылку - поищите поиском "Итерационная формула Герона". Получается, что это одно и тоже, поскольку в этой статье написано, что эту же формулу можно получить, применяя метод Ньютона к решению уравнения а - х^2 = 0.
67. Elisy 952 25.10.13 07:48 Сейчас в теме
(63) Пересмотрите, пожалуйста, вычисление начального значения источник.x / 2. К данной задаче подойдет метод грубой оценки. Можно посмотреть здесь: http://infostart.ru/public/204916/
68. for_sale 981 24.04.14 18:57 Сейчас в теме
простите за глупый вопрос - а зачем нужна пустая таблица заданного размера? какой-то пример из жизни есть?
69. ildarovich 7956 24.04.14 22:39 Сейчас в теме
(68) Вообще-то таблица не совсем пустая, а с числами в заданном диапазоне.

В данной статье приведены примеры подсчета частоты символов в тексте, слов в тексте, квадратного корня с использованием такой таблицы.

В статье Будни автоматизации или "мне нужна программка для 3D упаковки" с помощью таких таблиц генерируются варианты расположения коробок в коробе при 3D упаковке.

В статье Выразить строку как число и строку как дату в запросе с помощью таких таблиц получаются веса позиций.

В статье Агрегатное суммирование строк в запросе – сложно, но не невозможно эта таблица позволяет разбивать строки на символы.

Ну а чаще всего такие таблицы вспоминают, когда нужно сформировать "календарь" - множество дат в заданном диапазоне.

Все это реальные практические задачи.
70. chmv 01.07.14 10:19 Сейчас в теме
71. ildarovich 7956 06.11.14 20:15 Сейчас в теме
Нашлось еще одно применение для порождающего запроса. С его помощью можно получать готовый массив любого заданного размера N, содержащий последовательность чисел от 0 до N - 1. Этот массив затем, например, можно загрузить в нужную колонку таблицы значений, чтобы перенумеровать ее строки, не используя цикл. Такой способ всего примерно в 3 раза медленнее нумерации в цикле (для файловой базы).
Все необходимые для решения этой задачи функции (prototext, ЧисловаяПоследовательностьТаблицей, ЧисловаяПоследовательностьМассивом) в силу их компактности приведены в статье Минимализмы.
72. eugeniezheludkov 45 14.01.15 05:07 Сейчас в теме
я как то использовал подобные трюки на высоконагруженной системе, ммммалюсенький запрос который ничего не выбирал из таблиц ИБД, а только порождал данные быстрей чем в коде .... доооолго же мы не могли понять куда девается вся память, проц и канал связи на сервере с 16 гигами оперативы и 48 ядрами (точно не помню количество) при работе всего 40 пользователей, а вы представьте что ваш запрос запустят одновременно 40 человек, а не вы один в песочнице..... перенес все на клиентскую сторону (в код) и сервер вздохнул свободной грудью :) данные у всех генерились разные уникальные исходя из входного параметра, с тех пор в 1с я никогда не юзаю запросы для длинных вычислений или генераций данных ... нужно распределять нагрузку ! но если есть деньги на хороший сервер или это файловый вариант то конечно можно и побаловаться, в крайнем случае если нужно сгенерить много данных и быстрей чем позволяет 1С то можно через JS на клиенте через комобъекты, а если и этого не достаточно то GLPK.exe в макет (типа МАТЛАБ только Опенсорсный и работает как внешний интерпретатор с командной строки или файла, может вести расчеты на видеокарте) на клиенте
73. ildarovich 7956 14.01.15 12:35 Сейчас в теме
(72) eugeniezheludkov, "подобные трюки" - интересно было бы на них посмотреть (малюсенький запрос), чтобы оценить степень подобия. В данном случае ни на одном шаге данных не больше, чем нужно будет в итоге, поэтому вряд ли будет перегрузка по-сравнению с другими решениями.

Но все же основное назначение данного метода - это не формирование таблиц для последующего использования вне запроса, а формирование таблиц для использования внутри запроса. Оказалось, что сформировать пустую таблицу значений с заданным числом строк или пронумерованную таблицу в коде все же несколько быстрее (если делать это правильно).
74. eugeniezheludkov 45 20.01.15 07:39 Сейчас в теме
(73) сегодня постараюсь в истории хранилища откопать старые варианты функций, но вот навскидку нашел в коде одну из вешающих сервер в запросном варианте:
на складе применяется адресное хранение, адреса вида Б01-01-1, задача оптимизировать хронометраж сотрудников т.е найти ближайшую секцию для него чтобы при этом он шел в одном направлении, равномерно выполняя свою работу



это не порождающая функция, а анализирующая к сожалению , функция элементарная но именно она съедала кучу памяти и процессора пока выполнялась в виде запроса.. но у нас были и порождающие тоже постараюсь вспомнить как они выглядели и где применялись ранее (помню что по их результатам диаграмма ганта рисовалась нехилая ), чтоб не быть голословным ... да и код я все-же удалю позже т.к подписывал "неразглашение" и все такое
75. ildarovich 7956 20.01.15 13:21 Сейчас в теме
(74) eugeniezheludkov, как я понял, запрос был в функции "получить секции". То есть типа того, что там генерировались все соседние секции и отсекались не пройденные? Но разве структура секций не хранится в справочнике "топология"? Зачем генерировать секции?
Без самого запроса вникнуть тяжело.
Вообще задача интересная... Можно было бы покопаться, если бы было больше исходных данных.
77. eugeniezheludkov 45 20.01.15 15:01 Сейчас в теме
(75) нееет в "получить секции" запрос из самопального регистра а не справочника, да неважно там не сильная нагрузка идет её вообще из кода можно убрать. загружающим запросом была реализована лишь вот эта логика:
 
    НомерПервойСекции = Число(Сред(НачальнаяСекция,5,2));
    НомерПоследнейСекции = Число(Сред(КонечнаяСекция,5,2));
    НомерТекущейСекции = Число(Сред(Секция,5,2));
    dx = НомерТекущейСекции - НомерПервойСекции; dx = ?(dx<0,-dx,dx);
    dy = НомерПоследнейСекции - НомерТекущейСекции; dy = ?(dy<0,-dy,dy);
    Если dx>dy Тогда
        Возврат КонечнаяСекция;
    Иначе                       
        Возврат НачальнаяСекция;
Показать

вообщем просмотрел конфигурацию аж до июня 14 года , но там уже было исправлено, а еще раньше нет , только по памяти пытаться
но смысл запроса был таков, что на вход подаются строки типа 01 и 56 и текущая позиция тоже строка к примеру 10 нужно запросом выяснить к чему 10 ближе к 01 или к 56 выдать ответ 01 .. да это тоже не важно , а важно то что в профайлере скуля этот запрос был на первом месте по заниманию ресурсов несмотря на то что он не выбирал данные, временные таблицы уничтожались
78. ildarovich 7956 20.01.15 16:43 Сейчас в теме
(77) eugeniezheludkov, задачу понял, у меня есть вариант преобразования строки в число в запросе. На взгляд затраты в нем мизерные. Никто пока не жаловался.
Вообще меня эта тема довольно сильно интересует. Иногда из любви к изобретательству стараюсь делать запросами даже то, что, возможно, лучше делать кодом. Поэтому обращаю внимание на границы применимости запросной техники и возможные проблемы.
76. DrZombi 304 20.01.15 13:58 Сейчас в теме
Народ, шот не пойму, все начиная от первого, Хвалят запрос. А ссылки на запрос Нет :(
Дайте хоть, кто ссыль?
79. ildarovich 7956 20.01.15 16:48 Сейчас в теме
(76) DrZombi, запрос в начале статьи http://infostart.ru/public/90367/
Вот он
ВЫБРАТЬ 0 КАК Х
ПОМЕСТИТЬ Регистр1
ОБЪЕДИНИТЬ
ВЫБРАТЬ 1
;
////////////////////////////////////////////////////////////­////////////////////
ВЫБРАТЬ Младшие.Х + 2 * Старшие.Х КАК Х
ПОМЕСТИТЬ Регистр2
ИЗ Регистр1 КАК Младшие, Регистр1 КАК Старшие
;
////////////////////////////////////////////////////////////­////////////////////
ВЫБРАТЬ Младшие.Х + 4 * Старшие.Х КАК Х
ПОМЕСТИТЬ Регистр4
ИЗ Регистр2 КАК Младшие, Регистр2 КАК Старшие
;
////////////////////////////////////////////////////////////­////////////////////
ВЫБРАТЬ Младшие.Х + 16 * Старшие.Х КАК Х
ПОМЕСТИТЬ Регистр8
ИЗ Регистр4 КАК Младшие, Регистр4 КАК Старшие
;
////////////////////////////////////////////////////////////­///////////////////
ВЫБРАТЬ Младшие.Х + 256 * Старшие.Х КАК Х
ПОМЕСТИТЬ Регистр16
ИЗ Регистр8 КАК Младшие, Регистр8 КАК Старшие
;
////////////////////////////////////////////////////////////­////////////////////
ВЫБРАТЬ Младшие.Х + 65536 * Старшие.Х КАК Х
ПОМЕСТИТЬ Регистр20
ИЗ Регистр16 КАК Младшие, Регистр4 КАК Старшие
Показать
В самой статье приведены примеры применения этой таблицы. В конце статьи еще есть функция, которая строит ТЕКСТ запроса по заданному количеству чисел.
80. ildarovich 7956 09.12.15 12:26 Сейчас в теме
Для применений, связанных с генерацией дат в заданном диапазоне, удобнее применять основание 3. Тогда получается три каскада: на выходе первого - 9, второго - 81, третьего - 6551 чисел, то есть примерно 8 лет. А если взять основание 2, то три каскада будет мало - 256 чисел, на год не хватит, а четыре много - 65536, то есть примерно 80 лет.
Для основания 3 и дат запрос будет иметь вид:
ВЫБРАТЬ 0 КАК Х
ПОМЕСТИТЬ Х_3
ОБЪЕДИНИТЬ ВЫБРАТЬ 1
ОБЪЕДИНИТЬ ВЫБРАТЬ 2
;
ВЫБРАТЬ 3 * Инь.Х + Янь.Х КАК Х
ПОМЕСТИТЬ Х_9
ИЗ Х_3 КАК Инь, Х_3 КАК Янь
;
ВЫБРАТЬ 9 * Инь.Х + Янь.Х КАК Х
ПОМЕСТИТЬ Х_81
ИЗ Х_9 КАК Инь, Х_9 КАК Янь
;
ВЫБРАТЬ ДОБАВИТЬКДАТЕ(&Х1, ДЕНЬ, 81 * Инь.Х + Янь.Х) КАК Х
ИЗ Х_81 КАК Инь, Х_81 КАК Янь
ГДЕ ДОБАВИТЬКДАТЕ(&Х1, ДЕНЬ, 81 * Инь.Х + Янь.Х) <= &Х2
Показать
А если сразу работать с датами, то вид:
ВЫБРАТЬ	&Х1 КАК Х
ПОМЕСТИТЬ Х2
ОБЪЕДИНИТЬ ВЫБРАТЬ ДОБАВИТЬКДАТЕ(&Х1, ДЕНЬ, 81 * 27)
ОБЪЕДИНИТЬ ВЫБРАТЬ ДОБАВИТЬКДАТЕ(&Х1, ДЕНЬ, 81 * 54)
;
ВЫБРАТЬ ДОБАВИТЬКДАТЕ(Инь.Х, ДЕНЬ, РАЗНОСТЬДАТ(&Х1, Янь.Х, ДЕНЬ) / 3) КАК Х
ПОМЕСТИТЬ Х4
ИЗ Х2 КАК Инь, Х2 КАК Янь
;
ВЫБРАТЬ ДОБАВИТЬКДАТЕ(Инь.Х, ДЕНЬ, РАЗНОСТЬДАТ(&Х1, Янь.Х, ДЕНЬ) / 9) КАК Х
ПОМЕСТИТЬ Х16
ИЗ Х4 КАК Инь, Х4 КАК Янь
;
ВЫБРАТЬ ДОБАВИТЬКДАТЕ(Инь.Х, ДЕНЬ, РАЗНОСТЬДАТ(&Х1, Янь.Х, ДЕНЬ) / 81) КАК Х
ИЗ Х16 КАК Инь, Х16 КАК Янь
ГДЕ ДОБАВИТЬКДАТЕ(Инь.Х, ДЕНЬ, РАЗНОСТЬДАТ(&Х1, Янь.Х, ДЕНЬ) / 81) <= &Х2
Показать
84. bintape 17.11.16 07:56 Сейчас в теме
(80)

Подскажите, как будет выглядеть запрос по работе с датами по основанию 4 ?
85. ildarovich 7956 17.11.16 09:28 Сейчас в теме
(84) batan,
ВЫБРАТЬ 0 КАК Х
ПОМЕСТИТЬ Х_4
ОБЪЕДИНИТЬ ВЫБРАТЬ 1
ОБЪЕДИНИТЬ ВЫБРАТЬ 2
ОБЪЕДИНИТЬ ВЫБРАТЬ 3
;
ВЫБРАТЬ 4 * Инь.Х + Янь.Х КАК Х
ПОМЕСТИТЬ Х_16
ИЗ Х_4 КАК Инь, Х_4 КАК Янь
;
ВЫБРАТЬ 16 * Инь.Х + Янь.Х КАК Х
ПОМЕСТИТЬ Х_256
ИЗ Х_16 КАК Инь, Х_16 КАК Янь
;
ВЫБРАТЬ ДОБАВИТЬКДАТЕ(&Х1, ДЕНЬ, 256 * Инь.Х + Янь.Х) КАК Х
ИЗ Х_256 КАК Инь, Х_256 КАК Янь
ГДЕ ДОБАВИТЬКДАТЕ(&Х1, ДЕНЬ, 256 * Инь.Х + Янь.Х) <= &Х2
Показать
Ibrogim; bintape; +2 Ответить
86. Ibrogim 1336 25.03.19 20:27 Сейчас в теме
После прочтения только один вопрос остался у меня. Как поставить автору больше одного плюса ...
87. PerlAmutor 158 07.07.19 20:31 Сейчас в теме
ВЫБРАТЬ Младшие.Х + 65536 * Старшие.Х КАК Х
ПОМЕСТИТЬ Регистр20
ИЗ Регистр16 КАК Младшие, Регистр4 КАК Старшие


А тут вместо "Регистр4" не должно быть "Регистр16"?
88. ildarovich 7956 08.07.19 11:33 Сейчас в теме
(87) Регистр4, Регистр16 - это названия таблиц, хранящих всевозможные комбинации бит в соответствующем количестве разрядов. Регистр4 - четырехбитный регистр, в нем всего 16 разных битовых комбинаций или, что тоже самое, чисел от 0 до 15., Регистр16 - 16-ти разрядный. Комбинируя эти регистры, получаем 20-ти разрядный регистр Регистр20, в котором всего 2^20 битовых комбинаций - примерно миллион.
Если скомбинировать два 16-ти разрядных регистра, то получится 32-х разрядный регистр. Там слишком большая таблица на выходе - 3,6 миллиарда строк. Для временных таблиц это запредельные величины, вряд ли нужные на практике.
89. trumanl 12 31.10.19 15:02 Сейчас в теме
(0) ildarovich, добрый день
Видимо из-за изменения форматирования текста на сайте пропал знак "<" В выражении "ИЗ Аргументы ЛЕВОЕ СОЕДИНЕНИЕ Регистр10 ПО (Х * Х У)"
90. ildarovich 7956 01.11.19 14:56 Сейчас в теме
92. DrAku1a 1757 20.09.24 20:30 Сейчас в теме
Новые возможности платформы 8.3.25 - ключевое слово ДОБАВИТЬ в запросе, как будто создана для порождающих запросов:
ВЫБРАТЬ
	ВЫРАЗИТЬ(1 КАК ЧИСЛО(10)) КАК П
ПОМЕСТИТЬ ВТ

ОБЪЕДИНИТЬ

ВЫБРАТЬ
	2
;

////////////////////////////////////////////////////////////­////////////////////
ВЫБРАТЬ
	ВТ1.П + ВТ2.П * 2 КАК П
ДОБАВИТЬ ВТ
ИЗ
	ВТ КАК ВТ1,
	ВТ КАК ВТ2
;


////////////////////////////////////////////////////////////­////////////////////
ВЫБРАТЬ
	ВТ1.П + ВТ2.П * 6 КАК П
ДОБАВИТЬ ВТ
ИЗ
	ВТ КАК ВТ1,
	ВТ КАК ВТ2
;

////////////////////////////////////////////////////////////­////////////////////
ВЫБРАТЬ
	ВТ1.П + ВТ2.П * 42 КАК П
ДОБАВИТЬ ВТ
ИЗ
	ВТ КАК ВТ1,
	ВТ КАК ВТ2
;

////////////////////////////////////////////////////////////­////////////////////
ВЫБРАТЬ
	ВТ1.П + ВТ2.П * 1806 КАК П
ДОБАВИТЬ ВТ
ИЗ
	ВТ КАК ВТ1,
	ВТ КАК ВТ2
;

////////////////////////////////////////////////////////////­////////////////////
ВЫБРАТЬ
	ВТ.П КАК П
ИЗ
	ВТ КАК ВТ
Показать
На выходе - 3 миллиона строк в таблице. И задействуется только одна временная таблица. Единственный небольшой минус - начинается не с 0, а с 1.
Прикрепленные файлы:
triviumfan; artbear; ildarovich; +3 Ответить
93. ildarovich 7956 21.09.24 11:06 Сейчас в теме
(92) Спасибо за подсказку, действительно, очень крутая фича. Во многих запросах позволит избежать переписывания из таблицу в таблицу. Возьму на вооружение. И очень многое можно компактней переписать!
Оставьте свое сообщение