Имя: Пароль:
1C
1С v8
Оптимальное написание запроса
, ,
0 pav_s45
 
13.12.12
08:32
Всем добрый день.
Подскажите пожалуйста, как будет оптимальнее написать запрос с левым соединением для получения значения свойства объекта.
Допустим нам нужно выбрать контрагентов и левым соединением присоединить значение свойства.

а теперь 3 варианта запроса.

1)
|ВЫБРАТЬ
|    Контрагенты.Ссылка,
|    ЗначенияСвойствОбъектов.Значение
|ИЗ
|    Справочник.Контрагенты КАК Контрагенты
|        ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.ЗначенияСвойствОбъектов КАК ЗначенияСвойствОбъектов
|        ПО Контрагенты.Ссылка = ЗначенияСвойствОбъектов.Объект
|ГДЕ
|    ЗначенияСвойствОбъектов.Свойство = &Свойство

По этому запросу я накопал такую информацию : во первых условие ГДЕ накладывается после соединения и что неоптимально выбирать все записи из регистра, и второе мне поведал один товарищ :"при левом соединении нельзя накладывать отбор на правую таблицу", не знаю что он имел ввиду.

второй вариант запроса, с использованием вложенного запроса
2)
|ВЫБРАТЬ
|    Контрагенты.Ссылка,
|    ВложенныйЗапрос.Значение
|ИЗ
|    Справочник.Контрагенты КАК Контрагенты
|        ЛЕВОЕ СОЕДИНЕНИЕ (ВЫБРАТЬ
|            ЗначенияСвойствОбъектов.Объект КАК Объект,
|            ЗначенияСвойствОбъектов.Значение КАК Значение
|        ИЗ
|            РегистрСведений.ЗначенияСвойствОбъектов КАК ЗначенияСвойствОбъектов
|        ГДЕ
|            ЗначенияСвойствОбъектов.Свойство = &Свойство) КАК ВложенныйЗапрос
|        ПО Контрагенты.Ссылка = ВложенныйЗапрос.Объект

тут меня смутило то что в этой статье
http://1cexpo.ru/metodiki/20-tipichnye-prichiny-neoptimalnoj-raboty-zaprosov-i-metody-optimizaczii.html
написано что соединения с вложенными запросами это не есть хорошо и нужно писать используя временные таблицы.

итак третий запрос - пакетный, с использованием временных таблиц.
3)
|ВЫБРАТЬ
|    ЗначенияСвойствОбъектов.Объект,
|    ЗначенияСвойствОбъектов.Значение
|ПОМЕСТИТЬ ЗСО
|ИЗ
|    РегистрСведений.ЗначенияСвойствОбъектов КАК ЗначенияСвойствОбъектов
|ГДЕ
|    ЗначенияСвойствОбъектов.Свойство = &Свойство
|;
|
|////////////////////////////////////////////////////////////////////////////////
|ВЫБРАТЬ
|    Контрагенты.Ссылка,
|    ЗСО.Значение
|ИЗ
|    Справочник.Контрагенты КАК Контрагенты
|        ЛЕВОЕ СОЕДИНЕНИЕ ЗСО КАК ЗСО
|        ПО Контрагенты.Ссылка = ЗСО.Объект
|;
|
|////////////////////////////////////////////////////////////////////////////////
|УНИЧТОЖИТЬ ЗСО

И вопрос у меня такой, как все таки делать правильнее? или может есть ещё какой вариант который вы используете. Подскажите пожалуйста. Раньше всегда делал соединение к вложенным запросам и не парился, прочитал статью и решил разобраться. Заранее спасибо.
1 Sammo
 
13.12.12
08:34
В первом варианте классическая ошибка. Такое где автоматически неявно преобразует левое соединение во внутреннее.
Кстати, как вариант такое условие можно запихивать в соединение ПО
2 pav_s45
 
13.12.12
08:35
|ВЫБРАТЬ
|    Контрагенты.Ссылка,
|    ЗначенияСвойствОбъектов.Значение
|ИЗ
|    Справочник.Контрагенты КАК Контрагенты
|        ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.ЗначенияСвойствОбъектов КАК ЗначенияСвойствОбъектов
|        ПО Контрагенты.Ссылка = ЗначенияСвойствОбъектов.Объект
И ЗначенияСвойствОбъектов.Свойство = &Свойство

так ?
3 YHVVH
 
13.12.12
08:37
(0) первый вариант нормуль, остальное от лукавого
4 mzelensky
 
13.12.12
08:38
(0) если выборка в

|ВЫБРАТЬ
|    ЗначенияСвойствОбъектов.Объект,
|    ЗначенияСвойствОбъектов.Значение
|ПОМЕСТИТЬ ЗСО
|ИЗ
|    РегистрСведений.ЗначенияСвойствОбъектов КАК ЗначенияСвойствОбъектов
|ГДЕ
|    ЗначенияСвойствОбъектов.Свойство = &Свойство
|;
|


Предполагает большой объем данных, то лучше через ВТ.
Если маленький, то можно даже и первый вариант.

""при левом соединении нельзя накладывать отбор на правую таблицу"" - бред. Хотя может ты просто не так понял
5 mzelensky
 
13.12.12
08:39
(2) да
6 pav_s45
 
13.12.12
08:39
А как же классическая ошибка и неявное внутреннее соединение?
Я вот с этим неявным внутренним соединением немного затупил, пытаюсь понять как оно преобразуется, сижу вот рисую на бумажки, преобразуется из за того что условие накладывается после соединения на результат соединения, правильно понимаю?
7 YHVVH
 
13.12.12
08:43
(6) у тебя записи NULL отсеются просто и все по условию
8 pav_s45
 
13.12.12
08:56
проверил в консоли, теперь понял что такое неявное преобразование соединения во внутреннее.
Получается что если мне нужно все записи из справочника первый запрос не выдаст верные даннные. выдаст только те ссылки для которых заполнено значение свойства. перенес условие в соединение ПО, так нормально. Значит все таки первый вариант не нормуль)). Получается в данном случае два варианта, перенос условия в соединение ПО и использование временных таблиц ?
9 YHVVH
 
13.12.12
09:00
(8) нормуль, у тебя же по условию должны записи вернуться только с нужным свойством
10 Lama12
 
13.12.12
09:01
Вроде в (0) ошибки нету.
Ошибка была бы если б еще и "Свойство" попытался разъименовать.
Но я тоже предпочитаю такие условия в соединения выносить.
11 pav_s45
 
13.12.12
09:02
сорри, это моя ошибка, нужно вернуть все записи без исключения и где есть значение свойства и где оно не заполнено
12 Sammo
 
13.12.12
09:04
(9) У него левое. Типа все контрагенты + свойство если есть.
Правда при такой логике я бы добавил обработку на Есть NULL у ЗначенияСвойствОбъектов.Значение
13 Sammo
 
13.12.12
09:04
+12 чтобы результат запроса не возвращал нулл.
14 pav_s45
 
13.12.12
09:09
итак подытожим:
допустим тип значения свойства - число
тогда запрос будет выглядеть так?
|ВЫБРАТЬ
|    Контрагенты.Ссылка,
|    ЕСТЬNULL(ЗначенияСвойствОбъектов.Значение,0) Как Значение
|ИЗ
|    Справочник.Контрагенты КАК Контрагенты
|        ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.ЗначенияСвойствОбъектов КАК ЗначенияСвойствОбъектов
|        ПО Контрагенты.Ссылка = ЗначенияСвойствОбъектов.Объект
|        И ЗначенияСвойствОбъектов.Свойство = &Свойство

и если предполагается большой объем данных, то используем временные таблицы ?
15 kosts
 
13.12.12
09:21
(14) Я бы так и сделал.
Временную таблицу как раз не вижу смысла делать, т.к. в реальных запросах первая таблица (тут это контрагенты) скорее всего будет не по всем элементам (контрагентам), а виртуальная таблица будет заполнена для всех контрагентов.
16 pav_s45
 
13.12.12
09:23
Всем спасибо, вроде все более менее по полочкам разложилось)