gifts2017

Тонкости СКД: Особенности отбора при использовании временных таблиц

Опубликовал Владимир Семенов (kruglay) в раздел Программирование - Практика программирования

При создании запросов мы часто используем временные таблицы. Недавно столкнулся с тем что запрос в СКД не совсем корректно отрабатывал.

При создании запросов мы часто используем временные таблицы. Недавно столкнулся с тем что запрос в СКД не совсем корректно отрабатывал.

Рассмотрим пакетный запрос:

ВЫБРАТЬ
   
ФизическиеЛица.Ссылка КАК Ссылка,
   
ФизическиеЛица.Пол
ПОМЕСТИТЬ ВТ
ИЗ
   
Справочник.ФизическиеЛица КАК ФизическиеЛица

ИНДЕКСИРОВАТЬ ПО
   
Ссылка
;

////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ
   
ФизическиеЛица.Ссылка КАК Ссылка,
   
ФизическиеЛица.Пол КАК Пол,
    isnull(
ВложенныйЗапрос.Количество,0) КАК Количество
{ВЫБРАТЬ
    Ссылка.*,
   
Пол.*,
   
Количество}
ИЗ
   
Справочник.ФизическиеЛица КАК ФизическиеЛица
        ЛЕВОЕ СОЕДИНЕНИЕ (ВЫБРАТЬ
           
КОЛИЧЕСТВО(ВТ.Ссылка) КАК Количество
       
ИЗ
           
ВТ КАК ВТ) КАК ВложенныйЗапрос
        ПО (ИСТИНА)
{ГДЕ
    ФизическиеЛица.Ссылка.*,
   
ФизическиеЛица.Пол.*,
   
ФизическиеЛица.ИНН}

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

Когда мы не накладываем никаких отборов, то все работает замечательно(рис.1).


                                         Рис.1
Но если нам захочется добавить отбор по сотруднику или по полу

                                                            Рис.2

То получится не совсем то что мы ожидаем. В поле «Количество» получаем 4, хотя по идее там должно быть 48(рис.3) , т.к. отбор мы осуществляем в последней таблице.


                                                    рис.3

Разберемся почему такое происходит. Перед формированием отчета наш запрос автоматически оптимизируется средствами СКД что как мы видели может привести к неожиданным результатам. Рассмотрим запрос, который получился после обработки СКД:

ВЫБРАТЬ
   
ФизическиеЛица.Ссылка КАК Ссылка
ПОМЕСТИТЬ ВТ
ИЗ
   
Справочник.ФизическиеЛица КАК ФизическиеЛица
ГДЕ
   
ФизическиеЛица.Пол =
   
И ФизическиеЛица.Ссылка =

ИНДЕКСИРОВАТЬ ПО
   
Ссылка
;

////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ
   
ФизическиеЛица.Ссылка КАК Ссылка,
   
ФизическиеЛица.Пол КАК Пол,
    isnull(
ВложенныйЗапрос.Количество,0) КАК Количество,
   
ФизическиеЛица.Представление КАК СсылкаПредставление
ИЗ
   
Справочник.ФизическиеЛица КАК ФизическиеЛица
        ЛЕВОЕ СОЕДИНЕНИЕ (ВЫБРАТЬ
           
КОЛИЧЕСТВО(ВТ.Ссылка) КАК Количество
       
ИЗ
           
ВТ КАК ВТ) КАК ВложенныйЗапрос
        ПО (ИСТИНА)
ГДЕ
   
ФизическиеЛица.Пол =
   
И ФизическиеЛица.Ссылка =

В запрос были добавлены две строчки с условиями, которые и делают отбор во временной таблице. Чтобы наш запрос на СКД отработал так как мы хотим нужно убрать галочку «Автозаполнение» (рис.4) и на закладке «Компоновка данных» в конструкторе запроса у последней таблицы выбрать необходимые поля для вывода в отчет (рис.5).


                                                    рис.4


                                                                рис.5
После проделанных манипуляций формируем отчет и получаем нужный нам результат.


                                                            рис.6

См. также

Подписаться Добавить вознаграждение

Комментарии

1. Nick (Puk2) 15.09.14 12:13
Автозаполнение является причиной многих "проблем" (например, параметры и поля виртуальных таблиц), поэтому при использовании в отчетах, не являющихся слишком простыми, лучше отказаться от автозаполнения, либо прямо указывать поля, отборы и параметры для компоновки данных, например
{(Организация)}
. Если не ошибаюсь, ручное указание позволяет сохранить функцию автозаполнения. Вообще в вашем примере автоматический отбор сработал очень даже предсказуемо и корректно, поля с одинаковым именем, типом и источником фильтруются одинаково.

P.S. Замечания по запросу: 1) временная таблица уже содержит все записи справочника "физические лица", поэтому во втором запросе не нужно опять обращаться к таблице справочника, а должно быть соединение временной таблицы со вложенной таблицей (из этой же временной). 2) Так как вы получаете записи из таблицы справочника без соединений, то достаточно использовать оператор Количество() без указания слова Различные, т.к. это дополнительная нагрузка на СУБД из-за лишнего перебора данных.
sandybaev; AlexiyI; Nefertary; ekaterinaeon; davdykin; +5 Ответить 2
2. Яков Коган (Yashazz) 15.09.14 15:16
Обращаться к полю из присоединяемой таблицы без ЕСТЬNULL, если соединение не внутреннее - имхо, моветон.
3. Сергей Вн (EmpireSer) 15.09.14 14:43
(1), (2),
А это имеет смысл для "демонстрационного" запроса?

P.S. Я не считаю, что на запросах с пометкой "Запрос особой смысловой нагрузки не несет" нужно учится.
4. Владимир Семенов (kruglay) 15.09.14 13:39
(1) Puk2,
Спасибо за конструктивный комментарий.
Почему вы считаете, что отбор сработал предсказуемо? Во временной таблице нам необходимо получить все записи справочника, а если стоит галочка "Автозаполнение", то мы получим записи соответствующие критериям отбора(рис.3 т.е. всего 4 записи вместо 48). Источники мы используем разные: временную таблицу, и справочник физЛиц. Если я буду использовать в качестве источника только временную таблицу, то никакой наглядности в данном примере не будет, хотя результат и будет тем же. Насчет различные это я поправлю.
5. Владимир Семенов (kruglay) 15.09.14 13:41
(3) EmpireSer,
Данный запрос был смоделирован, чтобы его можно было просмотреть в любой конфе в которой есть справочник физЛиц. Кому надо тот почерпнет нужную информацию.
6. Артем Целовальников (slazzy) 15.09.14 16:08
(4) kruglay,
Почему вы считаете, что отбор сработал предсказуемо?

Потому что это принцип работы СКД, он всегда так устанавливает отборы :) это базовые сведения при работе с СКД и называть их "тонкости" несколько странно.

Автозаполнение ничего плохого не несет в себе, достаточно нужный отбор вынести в фигурные скобки и устанавливать отбор по этому полю.
 Рассмотрим пакетный запрос:

ВЫБРАТЬ
    ФизическиеЛица.Ссылка КАК Ссылка,
    ФизическиеЛица.Пол
ПОМЕСТИТЬ ВТ
ИЗ
    Справочник.ФизическиеЛица КАК ФизическиеЛица

ИНДЕКСИРОВАТЬ ПО
    Ссылка
;

////////////////////////////////////////////////////////////­////////////////////
ВЫБРАТЬ
    ФизическиеЛица.Ссылка КАК Ссылка,
    ФизическиеЛица.Пол КАК Пол,
    ВложенныйЗапрос.Количество КАК Количество
{ВЫБРАТЬ
    Ссылка.*,
    Пол.*,
    Количество}
ИЗ
    Справочник.ФизическиеЛица КАК ФизическиеЛица
        ЛЕВОЕ СОЕДИНЕНИЕ (ВЫБРАТЬ
            КОЛИЧЕСТВО(РАЗЛИЧНЫЕ ВТ.Ссылка) КАК Количество
        ИЗ
            ВТ КАК ВТ) КАК ВложенныйЗапрос
        ПО (ИСТИНА)
{ГДЕ
    ФизическиеЛица.Ссылка.* КАК СсылкаОтбор,
    ФизическиеЛица.Пол.* КАК ПолОтбор} 
...Показать Скрыть


И отборы устанавливать по полям СсылкаОтбор и ПолОтбор.
7. John Smith (PiccaHut001) 15.09.14 19:14
(6) slazzy, 1C - самая логичная и предсказуемая система, созданная марсианами для людей. Признак измерения "обязательный" уже не работает, надо каждое поле заводить по 2 раза - первый для отбора, второй для выборки с запретом отбора. Всё отлично работает, жду не-дождусь конфигуратора по 6 ифон
8. Владимир Семенов (kruglay) 15.09.14 18:15
(6) slazzy,
Большинство статей на инфостарте это базовые сведения, но тем не менее найти информацию в интернете по данному вопросу было проблематично. Только после прочтения Радченко я нашел причину и описал ее здесь.
Я и не говорю, что автозаполнение это плохо, просто показал вариант, когда данное свойство надо использовать осторожно
И отборы устанавливать по полям СсылкаОтбор и ПолОтбор

Это хорошо, что в данном примере всего несколько полей, а если их будет 10,20 вы для каждого будете придумывать синоним, не считаю это рациональным.
9. Артем Целовальников (slazzy) 15.09.14 22:06
(7) PiccaHut001, оптимизация это палка о двух концах :) данная работа отборов в СКД сделана прежде всего для оптимизации и она не понимает почему в данном случае отбор надо накладывать только на второй запрос из пакета, а не на оба. Чтобы она поняла, надо ей подсказать. Ну или просто переименовать поля в первом запросе, к примеру.

(8) kruglay, извиняюсь, но мне в страшном сне сложно представить отчет, в котором понадобится более 10 отборов. А уж про 20-30 я не буду говорить :)
10. Павел (Yimaida) 16.09.14 00:55
Только после прочтения Радченко я нашел причину и описал ее здесь.

Думаю, дальше можно не комментировать. Читать книгу и делится выводами в виде статьи и даже не сделать ссылку на книгу... Гляди сейчас и посыплются особенности, тонкости и т.п. Ну и отдельное внимание заслуживает текст запроса, прям для новичков. Причем статья, как я понял, редактировалась, хотя в данном случае ЕСТЬNULL эффекта не даст, т.к. условие соединения "Истина".

P.S. Дорогие новички, и не окрепшие умы, читайте сначала литературу, а потом инфостарт и т.п.


Andre_ultra; valiylab; SeiOkami; Evil Beaver; dj_serega; VasMart; Puk2; Yashazz; rozer; fishca; +10 Ответить 1
11. Владимир Семенов (kruglay) 16.09.14 20:30
(10) Yimaida,
Многоуважаемый старичок думаю в вашем комментарии вообще нет особого смысла. Данная статья писалась именно для тех кто недавно работает с 1с, СКД. И именно поэтому запрос простой, а если вам так хочется посмотреть на многострочные запросы и по разбираться в них откройте конфу например ЗУП. В указании первоисточника не вижу смысла, это не курсовая где указывается используемая литература. Если бы была похожая статья на инфостарте или другом источнике я бы ее указал.
12. Яков Коган (Yashazz) 17.09.14 11:26
(11)
"В указании первоисточника не вижу смысла, это не курсовая где указывается используемая литература"
Конечно, не курсовая. Это просто передирание методической литературы, т.е. плагиат. И попытка заработать на оном некоторые плюсы.
SeiOkami; Yimaida; +2 Ответить 1
13. Александр Крынецкий (echo77) 17.09.14 12:08
Вот еще одна публикация на тему, но здесь описывается как это обойти с установленной галкой автозаполнение
http://infostart.ru/public/185880/

Считаю, что для молодых специалистов лучше все же начинать изучение СКД с установленной галкой автозаполнение, но сразу же учиться пользоваться консолью отчетов с СКД и смотреть что за запрос строит СКД.
Когда сложность отчетов вырастет и опыта наберетесь - составляйте схемы без автозаполнения
14. Павел (Yimaida) 17.09.14 13:15
(12) Запрос, как раз, не простой. Он, конечно, не сравнится с запросами в ЗУП, но в контексте данной статьи он сложный, т.к. содержит временную таблицу, соединение по ИСТИНА и функцию ЕСТЬNULL().
Что касается сути статьи, основная идея - это научиться отлаживать итоговый запрос, который нам выдала СКД. Так вот про то как это сделать не сказано ни слова. Каким инструментом это надо делать? И даже если бы Вы указали где увидеть итоговый запрос, статья является лишь плохим пересказом давно описанных вещей. И странно, что никого не удивило наличие одинаковых параметров "&П" для пола и для ссылки.

P.S. Мой комментарий предназначался не столько Вам лично, сколько тем кто будет читать Вашу публикацию (в терминах инфостарта)
15. Александр Полтава (Патриот) 24.09.14 10:18
Статья сводится к "при использовании автозаполнения в СКД произойдёт автозаполнение, которое не обязательно вам было необходимо" =)
Надеюсь кто-нибудь через пару лет автоматизирует процесс написания подобных статей, представляющих из себя, по сути, кривенький пример к какому-нибудь утверждению из книг по 1С. И тогда, наконец, люди смогут вздохнуть свободно и доверить статьеписание машинам =)
16. Никита Грызлов (nixel) 29.09.14 10:01
Я просто оставлю это здесь.

Разработка сложных отчетов. Система компоновки данных.

P.S. Изучайте инструмент, которым вы зарабатываете на жизнь. Помогает избежать многих "проблем".
Evil Beaver; +1 Ответить
17. haz haz (hazd) 05.10.14 23:45
у меня тоже такая затыка была, разобрался.
18. Владимир Созанский (vsozansky) 29.09.16 10:33
Отличный пост. Помог разобраться и намекнул, что надо копать мануал.
Спасибо.
19. Владимир Семенов (kruglay) 29.09.16 16:27
Для написания сообщения необходимо авторизоваться
Прикрепить файл
Дополнительные параметры ответа