Имя: Пароль:
1C
1С v8
v8: Объясните принцип ЛЕВОЕ соединение
,
0 BaHgaJI
 
12.02.13
11:25
ЛЕВОЕ соединение по идее должно выдавать всю левую таблицу и к ней уже
правую, в данном запросе так не происходит, выдает 980 записей хотя в левой таблице их 1000

ВЫБРАТЬ
   РеализацияТоваровТовары.Номенклатура,
   ПоступлениеТоваровТовары.Номенклатура КАК Номенклатура1
ИЗ
   Документ.РеализацияТоваров.Товары КАК ИРеализацияТоваровТовары
       ЛЕВОЕ СОЕДИНЕНИЕ Документ.ПоступлениеТоваров.Товары КАК ПоступлениеТоваровТовары
       ПО РеализацияТоваровТовары.Номенклатура = ПоступлениеТоваровТовары.Номенклатура
ГДЕ
   РеализацияТоваровТовары.Ссылка = &Ссылка
   И ПоступлениеТоваровТовары.Ссылка = &Ссылка1
1 rbcvg
 
12.02.13
11:26
КАК ИРеализацияТоваровТовары
2 BaHgaJI
 
12.02.13
11:27
(1) ошибся при копировании, запрос правильный
3 Wobland
 
12.02.13
11:28
не читая: а потом бах - и ГДЕ
4 BaHgaJI
 
12.02.13
11:28
Я понимаю если бы он больше записей выдал
5 Humandra
 
12.02.13
11:28
И ПоступлениеТоваровТовары.Ссылка = &Ссылка1
6 BaHgaJI
 
12.02.13
11:28
я понимаю что, что-то с ГДЕ, но что?
7 BaHgaJI
 
12.02.13
11:29
Через вложенный надо делать?
8 shuhard
 
12.02.13
11:29
(6) ГДЕ
   РеализацияТоваровТовары.Ссылка = &Ссылка
   И ПоступлениеТоваровТовары.Ссылка = &Ссылка1

не взлетит
9 Humandra
 
12.02.13
11:29
соединение правильное, условие неправильное. Сначала был джойн (верный), потом вы собственноручно убрали из его результата строки с ПоступлениеТоваровТовары.Ссылка есть налл
10 Humandra
 
12.02.13
11:31
если я верно понимаю задачу, то
И ПоступлениеТоваровТовары.Ссылка = &Ссылка1
надо перенести в условие соединения
11 Широкий
 
12.02.13
11:31
(0) А что будешь делать, в документе будет две одинаковых позиций?
12 zhig75
 
12.02.13
11:31
А без левого соединения тыща записей, проверял?
13 Flyd-s
 
12.02.13
11:31
Сначала отбирается из РеализацияТоваров.Товары, потом присоединяются строки из Документ.ПоступлениеТоваров.Товары, а потом накладываются условия
14 BaHgaJI
 
12.02.13
11:32
(11) не будет там ограничение на дублирование
15 BaHgaJI
 
12.02.13
11:32
(12) да
16 BaHgaJI
 
12.02.13
11:33
(10) понял, спасибо
17 sapphire
 
12.02.13
11:34
(16) Что ты понял?
18 Maxus43
 
12.02.13
11:34
(0) да убери ГДЕ и увидишь результат, наглядно
19 MaxisUssr
 
12.02.13
11:35
(0)
Это условие

ГДЕ
   РеализацияТоваровТовары.Ссылка = &Ссылка
   И ПоступлениеТоваровТовары.Ссылка = &Ссылка1

особенно строка

   И ПоступлениеТоваровТовары.Ссылка = &Ссылка1

будет действовать так:
1. Система получает строку "Номенклатура" - "Номенклатура1"
2. В этой строке проверяется условие:
ПоступлениеТоваровТовары.Ссылка = &Ссылка1
3. Вывод - если у тебя строка из таблицы "ПоступлениеТоваровТовары" НЕ присоединилась к таблице "РеализацияТоваровТовары" - данное условие автоматом выкидывает эту строку из таблицы.
Чтобы работало, перепиши так:

ВЫБРАТЬ
   РеализацияТоваровТовары.Номенклатура,
   ПоступлениеТоваровТовары.Номенклатура КАК Номенклатура1
ИЗ
   Документ.РеализацияТоваров.Товары КАК ИРеализацияТоваровТовары
       ЛЕВОЕ СОЕДИНЕНИЕ Документ.ПоступлениеТоваров.Товары КАК ПоступлениеТоваровТовары
       ПО РеализацияТоваровТовары.Номенклатура = ПоступлениеТоваровТовары.Номенклатура
И ПоступлениеТоваровТовары.Ссылка = &Ссылка1
ГДЕ
   РеализацияТоваровТовары.Ссылка = &Ссылка
20 Humandra
 
12.02.13
11:39
а я бы и ГДЕ
   РеализацияТоваровТовары.Ссылка = &Ссылка

перенесла в соединение
нет, оптимизатор конечно и так, скорее всего, скушает
и результат будет тот же
но имхо, так ясно видно, что соединять надо только некоторые строки, а не всю таблицу
21 sapphire
 
12.02.13
11:40
(20) Ну и... {недума}
22 sapphire
 
12.02.13
11:41
(20) И оптимизатор не при чем.
23 Humandra
 
12.02.13
11:44
(22) я к тому, что если бы не было оптимизатора, то сначала было бы соединение по всей таблице Документ.РеализацияТоваров.Товары

что не есть хорошо с точки зрения производительности.

и только потом наложение условия по ссылке.

Но оптимизатор, чаще всего, такие ситуации разрулит сам.

Правда, общетеоретически запросы не совсем эквивалентны. Но есть такое предположение, что в данном случае - результат будет одинаковый :)
24 sapphire
 
12.02.13
11:46
(23) Ничего подобного.
25 hhhh
 
12.02.13
11:48
еще так можно

ГДЕ
   РеализацияТоваровТовары.Ссылка = &Ссылка
   И (ПоступлениеТоваровТовары.Ссылка ЕСТЬ NULL
  ИЛИ ПоступлениеТоваровТовары.Ссылка = &Ссылка1)
26 Humandra
 
12.02.13
11:49
(23) давайте поспорим тогда :)

1) ЛОГИЧЕСКИ условия в ПО выполняются раньше чем ГДЕ
2) физически оптимизатору пофиг, где они будут
3) но не лучше ли явно указать, что соединяться будут только маленькие таблицы? Хотя бы для своего понимания.

где я не права?
27 Humandra
 
12.02.13
11:52
уточню: в (26) речь исключительно про запрос типа как в (0)

потому что с inner join - оптимизатору часто (на практике видела!) не все равно
28 BaHgaJI
 
12.02.13
11:55
(17) понял то что условием
И ПоступлениеТоваровТовары.Ссылка = &Ссылка1 я убераю строчки из реализации которых нет в поступлении
29 pessok
 
12.02.13
11:56
казалось бы, причем тут левое соединение?
30 Идентификатор
 
12.02.13
12:06
Зачем соединения, делай без них!! хД

Запрос = Новый Запрос;
Запрос.Текст = "

ВЫБРАТЬ
   РеализацияТоваровТовары.Номенклатура
ИЗ
   Документ.РеализацияТоваров.Товары КАК ИРеализацияТоваровТовары
     
ГДЕ
   РеализацияТоваровТовары.Ссылка = &Ссылка ";



Запрос1 = Новый Запрос;
Запрос1.Текст = "
ВЫБРАТЬ
     ПоступлениеТоваровТовары.Номенклатура КАК Номенклатура1
ИЗ
     Документ.ПоступлениеТоваров.Товары КАК ПоступлениеТоваровТовары

ГДЕ
   ПоступлениеТоваровТовары.Ссылка = &Ссылка1 ";




Структура = НовыйСтруктура("ЛевоеЗначение, ПравоеЗначение");



Для каждого строка из запрос.выполнить().выгрузить() цикл


   НайтиИСоединитьСЛЕВА(строка, запрос1.выполнить().выгрузить(), Структура)
   
   


КонецЦикла


Процедура НайтиИСоединитьСЛЕВА(Строк, табл2, труЪ)


оО =  Табл2.НАйти(строк.Номенклатура);

Если оО = неопределено тогда

Иначе

труЪ.Вставить(Строк, оО);

КонецЕсли



КонецПроцедуры
31 Идентификатор
 
12.02.13
12:06
п.с. не проверял :)
32 Идентификатор
 
12.02.13
12:09
оо, со структурой косяк :)
33 Идентификатор
 
12.02.13
12:12
Вот так совсем камильфо

Пока 2*2=4 цикл


Если запрос1.выполнить().выгрузить().Количество() = кол тогда
прервать
КОнецЕсли


НайтиИСоединитьСЛЕВА(выполнить().выгрузить().Количество()[кол], запрос1.выполнить().выгрузить(), Структура)


кол = кол+1;  
   
   


КонецЦикла
34 magicSan
 
12.02.13
12:22
При условии "где" отбор идет из результирующей таблицы в условии "по" в отборе участвует только правая таблица(только ан неё накладываются ограничения)
35 GANR
 
12.02.13
12:27
ПоступлениеТоваровТовары.Ссылка = &Ссылка1 ты рубишь NULL и превращаешь левое соединение во внутреннее - банальная ошибка.
36 smitru
 
12.02.13
12:27
мдя-я-я... за подобное:

Для каждого строка из запрос.выполнить().выгрузить() цикл

   НайтиИСоединитьСЛЕВА(строка, запрос1.выполнить().выгрузить(), Структура)
   
КонецЦикла

полагается "три года расстера без права переписки... фигачить выполнение запроса в цикле... мдя-я-я-я...
37 sapphire
 
12.02.13
12:27
(27) О каком оптимизаторе речь? Об 1С, или СУБД?
38 sapphire
 
12.02.13
12:28
(28) Молодец.
39 smitru
 
12.02.13
12:29
(37) Ух ты.. а у 1С есть встроенный оптимизатор запросов?????

Кинь плз ссылку на описание подобного чуда
40 GANR
 
12.02.13
12:30
(38) интересно, сколько веток в день с ошибкой (35) можно насчитать?
41 Идентификатор
 
12.02.13
12:32
(36) лол што ?) почитай про итераторы :)
42 smitru
 
12.02.13
12:44
(41) Ты это на экзамене по спецу будешь втирать преподам, когда тебя с треском выгонят за подобный изврат..
43 Идентификатор
 
12.02.13
12:45
а я на экзамене по спецу такое не написал бы )
44 Shurjk
 
12.02.13
12:45
Однако все таки соединения для многих остаются таинственным и мистическим действом.
45 Идентификатор
 
12.02.13
12:46
Для каждого строка из запрос.выполнить().выгрузить() цикл

   НайтиИСоединитьСЛЕВА(строка, запрос1.выполнить().выгрузить(), Структура)
   
КонецЦикла

(42) и где же тут запрос выполняется в цикле ?)
46 Humandra
 
12.02.13
12:48
(37) СУБД, оф коз
47 smitru
 
12.02.13
12:48
(45)

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

Т.е. при каждом выполнении

Для каждого строка из запрос.выполнить().выгрузить() цикл

У тебя будет выполняться запрос1 снова и снова...
48 Идентификатор
 
12.02.13
13:01
(47) ах ты про это :) тогда пардон, я то говорю про

Для каждого строка из запрос.выполнить().выгрузить() цикл
49 smitru
 
12.02.13
13:09
(48) Конструкция
Для каждого строка из запрос.выполнить().выгрузить() цикл

имхо, яркий пример было-кода :-)
У тебя Запрос.Выполнить() может быть пустой.. тогда зачем нужны издержки на всё остальное???

почему не сделать по-нормальному....
Результат = запрос.выполнить();
Если Результат.Пустой() тогда
....................
КонецЕсли;
50 Sorm
 
12.02.13
13:11
(0) Запомните уже - условие соединения на правую таблицу превращает левое соединение во внутреннее...
51 magicSan
 
12.02.13
13:13
этож где надо работать чтоб придумать такую замену запросу ...
52 trad
 
12.02.13
13:14
(50) условие условию рознь
53 Идентификатор
 
12.02.13
13:15
(49) быДло - код :))

ну будет пустой, что ж с того :) принципиальной разницы не вижу кроме имхо )

Ко всему ты придерешься )))  

Да и если ты не заметил, то весь код выше приведен мною - ярки пример как раз таки быдло кода и написан исключительно для фана, как впрочем и половина сообщений на мисте )
54 Sorm
 
12.02.13
13:16
(52) Согласен, но здесь все прозрачно.
55 Идентификатор
 
12.02.13
13:27
а (0) внимательно почитай http://1cexpo.ru/obuchenie-1s-predpriyatie/23-prakticheskoe-ispolzovanie-zaprosov-v-1s-8/46-soedinenie-zaprosov.html, доступно и понятно написано