baner

Работа

Соединения таблиц в запросах

Урок https://helpme1c.ru/yazyk-zaprosov-1s-8-3-dlya-nachinayushhix-programmistov-soedineniya#i-7

Описывают виды соединений

Соединения таблиц не путать с объединением таблиц.

При объединении таблиц в одну добавляются строки, а перечень полей (столбцов) не изменяется.

При соединениях таблиц строки соединяются по какому-то общему полю; общее поле из обоих таблиц не сливается в одно, а дублируется.

 

Рассматривают виды соединений таблиц:

перекрестное

левое внешнее

правое внешнее

внутреннее

полное

 

Пишут про использование псевдонимов полей (полные названия источников заменять на краткие).

 

Пишут про использование функции ЕСТЬNULL в запросах с соединениями, чтобы заменять отсутствующие значения на пустые значения (или нулевые, или какие надо значения.

Запрос, читающий выборку, выглядит так:

ВЫБРАТЬ

  ЕСТЬNULL(СтроковоеПоле, ЗначениеЕслиNULL) КАК псевдоним

  ЕСТЬNULL(ПолеСсылка, Справочник.ПустаяСсылка) КАК псевдоним

ИЗ

..

ПОЛНОЕ СОЕДИНЕНИЕ

...

ПО

...

 

Пишут про возможность последовательного соединения двух и более таблиц

Выбрать

Таблица1.Поле1

Таблица1.Поле2

ИЗ

ВНУТРЕННЕЕ СОЕДИНЕНИЕ

Таблица2.Поле2

ПО

Таблица1.Поле1=Таблица2.Поле1

ВНУТРЕННЕЕ СОЕДИНЕНИЕ

Таблица3.Поле2

ПО

Таблица1.Поле1=Таблица3.Поле1

 

 Дополнительная информация

Соединения таблиц в запросах

https://capitally.ru/1c-development/zaprosy/soedinenie-tablits-v-zaprose/

Не понял:

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

Если задвоения будут в динамическом списке, это может вызвать ошибку дублирования ключевого поля."

 

Пишут, что при левом соединении по ключевому полю левой таблицы не должно быть дублей!

 

Динамические списки https://capitally.ru/tag/dinamicheskij-spisok/

 

Пишут, как задать соединения (связи между таблицами) в конструкторе запросов

Пакетные запросы

https://programmist1s.ru/rabota-s-paketnyimi-zaprosami-v-1s/

Платформа «1С Предприятие» позволяет выполнить последовательно несколько запросов за один раз. В 1С это называется пакетом запросов. В рамках одного пакета каждый запрос разделяется «точкой с запятой».

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

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

Еще одна важная деталь в пользу пакетных запросов в 1С – это то, что в отличие от вложенных запросов мы можем получить отдельно результат каждого запроса в пакете.

 

Методы Выполнить() и ВыполнитьПакет()

Помимо метода Выполнить(), который поочередно выполнит все запросы в пакете и вернет результат последнего запроса, в 1С существует метод ВыполнитьПакет(). Он возвращает массив выборок каждого запроса в пакете. В примере выше выполняется как раз этот метод.

Далее работаем с результатом как с массивом:

МассивРезультатов = Запрос.ВыполнитьПакет();

Выборка1 = МассивРезультатов[0].Выбрать();

Если Выборка1.Следующий() Тогда

//Действия с выборкой 1

КонецЕсли;

ВыборкаВидыСубконто = МассивРезультатов[1].Выбрать();

 

Менеджер временных таблиц

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

Если необходимо сохранять данные временных таблиц для передачи от запроса к запросу, выполняя какие-либо действия, используется МЕНЕДЖЕР ВРЕМЕННЫХ ТАБЛИЦ.

 

Вот про менеджер временных таблиц http://1clenta.ru/pattern/130

Я не понял, вроде все аналогично работало и без этого менеджера

 

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

1) Запрос
В первом запросе формируется временная таблица (ВТ_Валюта) из данных справочника "Валюты". Используя менеджер временных таблиц можно передать таблицу (ВТ_Валюта) в другие запросы.

2) Запрос
Для того чтобы во втором запросе стала доступна таблица (ВТ_Валюта), необходимо свойству запроса "МенеджерВременныхТаблиц" присвоить "МенеджерВременныхТаблиц" полученный из первого запроса.

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

 

Вот еще https://helpf.pro/faq/view/1722.html


Узнать: срок жизни временной таблицы. Она же живет в пределах запроса или в пределах времени выполнения пакета запросов? Так что менеджер не нужен! Если ВТ надо передавать между запросами, которые выполняются с временными промежутками, тогда да, нужен МЕНЕДЖЕР ВРЕМЕННЫХ ТАБЛИЦ.


Вот понятно все изложено

http://chel1c.ru/%D0%BC%D0%B5%D0%BD%D0%B5%D0%B4%D0%B6%D0%B5%D1%80-%D0%B2%D0%B8%D1%80%D1%82%D1%83%D0%B0%D0%BB%D1%8C%D0%BD%D1%8B%D1%85-%D1%82%D0%B0%D0%B1%D0%BB%D0%B8%D1%86-1%D1%81/

Правда, что ли?

Как использовать таблицы из менеджера временных таблиц в запросах 1С

К сожалению, конструктор запроса не может видеть временные таблицы из менеджера. Поэтому запрос к временной таблице нужно либо писать вручную, либо все-таки воспользоваться конструктором, но указать в нем структуру временной таблицы.



Вот тоже детально понятно описано

https://курсы-по-1с.рф/%D0%B1%D0%B5%D1%81%D0%BF%D0%BB%D0%B0%D1%82%D0%BD%D0%BE%D0%B5/2020-01-09-when-should-i-use-the-temporary-table-manager-and-do-i-need-to-close-it-explicitly/



 

Вложенные запросы

Смотри, как выглядят!

 

 

Вот инфа про соединения и временные таблицы

https://infostart.ru/1c/articles/782802/

Показывает пример из Хрусталевой

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



Разница у Хрусталевой и у автора: у Хрустулевой тексты запросов, запуск запросов формируется в коде 1С. У Хрусталевой так сложно делается для случая, если выход первого запроса необходимо обработать средствами 1С (участие оператора или что), а после уже делается второй запрос.

У автора все в консоли запросов пакетным запросов, так что намного проще.



Цитата:

Здесь нет ничего сложного, кроме одной очень важной ремарки - перед наименованием нашей таблички мы ставим амперсант!

&ВнешниеДанные

С помощью амперсанта - мы конкретно указываем, что создаем не просто табличку, а Параметр, который необходим к заполнению при отработке нашего запроса.



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



Пишут: в запросах с соединениями наложение параметров на виртуальные таблицы лишь увеличивает время выполнения запроса? Тем более, если временные таблицы не индексированы?

https://infostart.ru/1c/articles/782802/

В комментах пишут:

параметры, наложенные на временные таблицы, лишь увеличивают время выполнения запроса?



Комментатор пишет:

Запрос1
ВЫБРАТЬ Продажи.* ИЗ ПродажиОборот(,,Номенклаура = (ВЫБРАТЬ вт.Номенклатура ИЗ вт КАК вт)) как Продажи
Запрос2
ВЫБРАТЬ Продажи.* ИЗ ПродажиОборот ВНУТРЕННЕЕ СОЕДИНЕНИЕ вт ПО ПродажиОборот.Номенклатура = втНоменклатура КАК Продажи


Это одинаковые для субд запросы. Причем во втором варианте СУБД автоматически индексирует "вт" по полям соединения, а в первом мы ОБЯЗАНЫ не забыть это делать сами (Хрусталёва забыла)



Фильтра не существует в субд. Он есть только в 1С , как вымышленная сущность, призванная избавить программистов 1С от грубых ошибок. Чтобы отфильтровать по желанию 1С записи из БД, реальный сервер sql выполнит ровно те же действия что и при соединении таблиц. Он переберёт все 150тыс записей регистра и сравнит их с 5ю записями документа. Ровно то же самое сделает он при простом соединении.

"причем она делает очень верно - сокращая таблицы регистров перед их Соединением с ВТ"
В том то и дело, что сокращения не происходит. Она дважды выполняет склеивание таблиц, тем самым увеличивая время запроса. В вырожденном случае когда в регистре ровно столько же записей сколько в документе (например сделали док поступления на 10 строк, потом делаем документ полной продажи на те же 10строк) , запрос Хрусталёвой будет выполнятся ровно вдвое ДОЛЬШЕ чем простое соединение виртуальной и временной таблиц, безо всяких предварительных условий

...

И еще раз.
Не бывает фильтрации таблиц регистра. Есть только join и where. Так работает субд, согласны с этим методисты 1С или нет, неважно.
Кстати фирма 1С при сдаче официального экзамена "Эксперт по технологическим вопросам" просит опиратся на логику именно sql запросов, а не методически верных книг "1С для чайников"





7. jan-pechka 242 11.02.18 17:26

(6)

Не бывает фильтрации таблиц регистра



....если Вы так уверены в этом, значит Вы умеете пользоваться этими всеми серверными sql-штучками, типа ExpressProfiler22wAddinSigned и др., и тем более есть возможность на реальном серваке протестить оба варианта запроса и выложить результаты производительности....



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



8. Sapiens_bru 3 11.02.18 18:30

(7)

Уверен. Есть возможность. Более того, тестировал лично месяц назад. Была задача по оптимизации запроса. Он выполнялся 12 секунд. Немного вроде, но очень уж часто пользователи к нему обращались.

Нашел ошибку предыдущего программиста - отсутствие индекса во временной таблице. Затем эта временная таблица идет как параметр-выборка к виртуальной и еще как левое соединение к этой же виртуальной. Примерно как вы делаете в исходной теме.

Поставил индекс к таблице - время запроса уменьшилось до 0.45с

Убрал вообще параметр из виртуальной таблицы - время запроса 0.3с

Все замеры выполнял минимум трижды, совпадали до сотых долей секунды.



25. buganov 155 11.03.20 06:37

А еще есть Seek predicates. И фильтры, если они наложены в четком порядке по индексу, как раз и попадут в секцию Seek. И при этом из большого регистра с диска поднимутся только то, что нужно без избыточных данных.


...

20. caponid 14.02.18 17:52

(10) sql для маленьких таблиц всегда игнорирует индексы. По моим исследованиям, индексы использовались после 5к строк - каким образом sql выбирает это количество, мне непонятно.



 

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

http://avditor.ru/index.php/programmirovanie-1s/50-1s-zaprosy-levoe-soedinenie-rabotaet-kak-vnutrennee-urezayutsya-dannye-iz-levoj-tablitsy

Смотри примеры запросов

внутреннее соединение вместо левого; (условие наложено на значение из правой таблицы, получается внутреннее соединение вместо левого. ? Так уберите условие, и будет нормальное левое соединение);

левое соединение с временной таблицей;

левое соединение со вложенным запросом.


Не понял примеры пока.

? Соединяются источники, а запрос выборки — один, из соединенных источников.

11.11.2020

Ромин С.А.