Как правильно сделать необязательное соединение в запросе СКД

1. paxan 26.04.20 06:11 Сейчас в теме
Здравствуйте. Подскажите как правильно реализовать в тексте запроса СКД соединение таблиц, которое будет выполняться только при заполненном параметре?
Пример допустим такой: Нужно выбрать либо всю номенклатуру, либо номенклатуру входящую в определенный список (например находящуюся в таб. части какого-то конкретного документа). Делать это через часть запроса ГДЕ не всегда удобно, поэтому хотелось бы понять как возможно сделать это через соединения таблиц.
Если сделать например так
"ВЫБРАТЬ
|	СпрНоменклатура.Ссылка
|ИЗ
|	Справочник.Номенклатура КАК СпрНоменклатура
|		{ВНУТРЕННЕЕ СОЕДИНЕНИЕ Документ.ПеремещениеТоваров.Товары КАК ПеремещениеТоваровТовары
|		ПО СпрНоменклатура.Ссылка = ПеремещениеТоваровТовары.Номенклатура}
|{ГДЕ
|	ПеремещениеТоваровТовары.Ссылка.*}"


Но при выполнении такого запроса есть большое подозрение что при неуказанном параметре ссылки на документ все равно происходит соединение таблиц (тк. запрос выполняется гораздо дольше чем при простой выборке из одного справочника). Если же параметр указать то отбора не происходит, все равно выбирается все. Когда подобное делал с использованием такой конструкции в ПостроителеЗапроса, то вроде все корректно работало, а в запросе СКД не так.
По теме из базы знаний
Ответы
Подписаться на ответы Инфостарт бот Сортировка: Древо развёрнутое
Свернуть все
2. dhurricane 26.04.20 09:19 Сейчас в теме
(1) Как я понимаю, под параметром Вы подразумеваете отбор по полю Ссылка, верно?

Такая конструкция, предложенная Вами, должна работать корректно. Единственное, чего на мой взгляд не хватает, это псевдонима для поля ссылки на документ. В Вашем варианте ссылка на позицию номенклатуры и ссылка на документ с точки зрения СКД - это одно и то же. Установите псевдоним:
...
{ГДЕ
   ПеремещениеТоваровТовары.Ссылка.* КАК ДокументПеремещения}
В этом случае при установке отбора на поле "ДокументПеремещения" в запросе будет появляться соединение с таблицей документа, а при отключении этого отбора соединение пропадет.
3. paxan 26.04.20 09:29 Сейчас в теме
(2)Да, нужен отбор по полю Ссылка. Попробую добавить псевдоним, спасибо.
4. paxan 26.04.20 09:40 Сейчас в теме
Чуть-чуть неправильный все-таки пример привел (исходный запрос довольно мудреный и смысла его нет тут писать, поэтому пытаюсь что попроще привести). В исходном запросе условие ГДЕ ставится не на результат запроса, а на вложенную таблицу запроса. Вот с ней-то и проблемы возникают, когда пытаешься эту вложенную таблицу сделать необязательной. Т.е. в таком случае:
"ВЫБРАТЬ
|	СпрНоменклатура.Ссылка
|ИЗ
|	Справочник.Номенклатура КАК СпрНоменклатура
|		{ВНУТРЕННЕЕ СОЕДИНЕНИЕ (ВЫБРАТЬ
|			ПеремещениеТоваровТовары.Номенклатура КАК Номенклатура
|		ИЗ
|			Документ.ПеремещениеТоваров.Товары КАК ПеремещениеТоваровТовары
|		{ГДЕ
|			ПеремещениеТоваровТовары.Ссылка.*}) КАК ВложенныйЗапрос
|		ПО СпрНоменклатура.Ссылка = ВложенныйЗапрос.Номенклатура}"
Показать


Пока плюнул на это и сделал через секцию ГДЕ снаружи запроса, т.е. вида {ГДЕ СпрНоменклатура.Ссылка В (Выбрать ... из Документ...)}, так точно работает. Чутьпозже попробую еще раз проверить как работает с вложенной таблицей, где ГДЕ определено внутри вложенной таблицы.
5. paxan 26.04.20 09:55 Сейчас в теме
Проверил, вот такой запрос если:

ВЫБРАТЬ ПЕРВЫЕ 100
	СпрНоменклатура.Ссылка
ИЗ
	Справочник.Номенклатура КАК СпрНоменклатура
		{ВНУТРЕННЕЕ СОЕДИНЕНИЕ (ВЫБРАТЬ
			ПеремещениеТоваровТовары.Номенклатура КАК Номенклатура
		ИЗ
			Документ.ПеремещениеТоваров.Товары КАК ПеремещениеТоваровТовары
		{ГДЕ
			(ПеремещениеТоваровТовары.Ссылка.*) КАК Документ}) КАК ВложенныйЗапрос
		ПО СпрНоменклатура.Ссылка = ВложенныйЗапрос.Номенклатура}
Показать


То без разницы стоит ли условие на ссылку документа или нет, оно просто не учитывается. Видать или так нельзя в принципе писать или не знаю где ошибка..
6. dhurricane 26.04.20 09:58 Сейчас в теме
(5) А отбор по полю "Документ" пользовательский? Есть ли возможность устанавливать отборы и/или параметры программно?
7. paxan 26.04.20 10:00 Сейчас в теме
Нет, все просто пользователем указывается. Программно ничего не изменяется.
8. dhurricane 26.04.20 10:09 Сейчас в теме
(7)
Программно ничего не изменяется.
Это я понимаю. Я говорю про то, что есть ли такая возможность?

Можно попробовать пойти путем, аналогичным отбору по сегментам в УТ:
ВЫБРАТЬ РАЗЛИЧНЫЕ
	Товары.Номенклатура КАК Номенклатура,
	ИСТИНА КАК Использование
ПОМЕСТИТЬ ВтОтбор
ИЗ
	Документ.ПеремещениеТоваров.Товары КАК Товары
{ГДЕ
	Товары.Ссылка.* КАК ДокументПеремещения}
;

////////////////////////////////////////////////////////////­////////////////////
ВЫБРАТЬ
	СпрНоменклатура.Ссылка КАК Ссылка
ИЗ
	Справочник._ДемоНоменклатура КАК СпрНоменклатура
		{ВНУТРЕННЕЕ СОЕДИНЕНИЕ ВтОтбор КАК ВтОтбор
		ПО СпрНоменклатура.Ссылка = ВтОтбор.Номенклатура}
{ГДЕ
	ВтОтбор.Использование КАК ИспользоватьОтборПоПеремещению}
Показать
При таком запросе при компоновке результата проверять, установлен ли отбор по документу перемещения, и синхронно ему устанавливать или сбрасывать отбор по полю "ИспользоватьОтборПоПеремещению", равному "Истина".
9. paxan 26.04.20 10:22 Сейчас в теме
Возможность есть конечно, но решил не усложнять, сделал через секцию ГДЕ (выше написал как). Так как вы привели пример тоже довольно интересно сделано, спасибо.
10. Const1C 16.04.24 12:00 Сейчас в теме
Для использования условного соединения в СКД, необходимо продублировать условие во внешней таблице. Т.е. сделать вот так:
ВЫБРАТЬ ПЕРВЫЕ 100
    СпрНоменклатура.Ссылка
ИЗ
    Справочник.Номенклатура КАК СпрНоменклатура
        {ВНУТРЕННЕЕ СОЕДИНЕНИЕ (ВЫБРАТЬ
            ПеремещениеТоваровТовары.Номенклатура КАК Номенклатура
        ИЗ
            Документ.ПеремещениеТоваров.Товары КАК ПеремещениеТоваровТовары
        {ГДЕ
            (ПеремещениеТоваровТовары.Ссылка.*) КАК Документ}) КАК ВложенныйЗапрос
        ПО СпрНоменклатура.Ссылка = ВложенныйЗапрос.Номенклатура}
{ГДЕ
            (ПеремещениеТоваровТовары.Ссылка.*) КАК Документ}
Показать
Оставьте свое сообщение

Для получения уведомлений об ответах подключите телеграм бот:
Инфостарт бот