Имя: Пароль:
1C
1С v8
Вопрос про запрос.
0 Target1025
 
14.05.20
10:42
"ВЫБРАТЬ
    |    ТребованиеНакладная.Номер КАК Номер,
    |    ЗначенияСвойствОбъектов.Значение КАК Значение
    |ИЗ
    |    Документ.ТребованиеНакладная КАК ТребованиеНакладная,
    |    РегистрСведений.ЗначенияСвойствОбъектов КАК ЗначенияСвойствОбъектов
    |ГДЕ
    |    ТребованиеНакладная.Ссылка = &ТН
    |    И ЗначенияСвойствОбъектов.Объект = &ТН
    |    И ЗначенияСвойствОбъектов.Свойство = &Причина";
    
    Запрос.УстановитьПараметр("ТН",ТН);
    Запрос.УстановитьПараметр("Причина",ПланыВидовХарактеристик.СвойстваОбъектов.НайтиПоНаименованию("Причина",Истина));
    ТЗ= Запрос.Выполнить().Выгрузить();

Пусть у меня такой упрощенный запрос. ПО замыслу, он должен вытащить номер Требования-накладной из ссылки на документ, и, если есть, значение допреквизита из РегистраСведений. Я рассчитывал, что если записи в РС нет, то там будет NULL, но запись ТН тоже не выбирается вообще.
1 NecroDog
 
14.05.20
10:48
Таблица регистра должна присоединяться левым соединением к таблице документа
2 Target1025
 
14.05.20
10:50
(1) Так?

    "ВЫБРАТЬ
    |    ТребованиеНакладная.Номер КАК Номер,
    |    ЗначенияСвойствОбъектов.Значение КАК Значение
    |ИЗ
    |    Документ.ТребованиеНакладная КАК ТребованиеНакладная
    |        ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.ЗначенияСвойствОбъектов КАК ЗначенияСвойствОбъектов
    |        ПО ТребованиеНакладная.Ссылка = ЗначенияСвойствОбъектов.Объект
    |ГДЕ
    |    ТребованиеНакладная.Ссылка = &ТН
    |    И ЗначенияСвойствОбъектов.Объект = &ТН
    |    И ЗначенияСвойствОбъектов.Свойство = &Причина";
3 RomanYS
 
14.05.20
10:52
(2) все условия на правую таблицу убрать из "где" и перенсти в условия соединения
4 Target1025
 
14.05.20
10:53
(1) К сожалению, так почему-то не работает тоже: если нет записи регистра по этому документу, то выборка пустая.
5 polosov
 
14.05.20
10:53
"ВЫБРАТЬ
    |    ТребованиеНакладная.Номер КАК Номер,
    |    ЕстьNULL(ЗначенияСвойствОбъектов.Значение, "Что-то там не то" КАК Значение
    |ИЗ
    |    Документ.ТребованиеНакладная КАК ТребованиеНакладная
    |    ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.ЗначенияСвойствОбъектов КАК ЗначенияСвойствОбъектов ПО
    |   ТребованиеНакладная.Ссылка = ЗначенияСвойствОбъектов.Объект
    |   И ЗначенияСвойствОбъектов.Свойство = &Причина"
6 Target1025
 
14.05.20
11:13
(3)(4)так заработало! можно теперь пояснить смысл действа "идеологически"? Почему не работало ранее и заработало сейчас?
7 Timon1405
 
14.05.20
11:18
8 Evgenchik
 
14.05.20
11:27
Накладывая условие через секцию ГДЕ на таблицу соединенную левым соединением, ты превращаешь его во внутреннее соединение. То есть сначала соединил, потом наложил условие ГДЕ. И в результате у тебя нет вообще строк в результате, так как нет строк в РС.
Второй вариант - ты говоришь, что номер из документа мы берем обязательно, а вот данные из РС подтянуться только при наличии отборов из соединения.
9 Target1025
 
14.05.20
12:24
(8) Посмотрел, подумал, считаю что дело несколько в ином. Секция ГДЕ делает ПОСТ-обработку получившейся таблицы, выкидывая все строки, не подошедшие под условние ГДЕ. Поэтому и вылетали из выборки пустые записи из РС. А так как иных и не было, выборка получалась пустая.
Т.е., вот этот запрос тоже отрабатывает идеально:

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

В том смысле, что пост-условие ГДЕ он не превращает во внутреннее соединение соединение таблицы. Она по прежнему соединяется левым соединением, и там есть запись Null при отсутствии записи в регистре сведений.
10 Timon1405
 
14.05.20
14:45
видимо в (8) "Накладывая условие через секцию ГДЕ на таблицу" следует читать как
"Накладывая условие через секцию ГДЕ на поля присоединяемой таблицы"
11 NecroDog
 
14.05.20
16:14
Есть порядок обработки инструкции SELECT. Он вот такой:
FROM
ON
JOIN
WHERE
GROUP BY
WITH CUBE или WITH ROLLUP
HAVING
SELECT
DISTINCT
ORDER BY

Инструкция AND в соединении выполняется до JOIN. Инструкция WHERE применяется к таблице, получившейся после JOIN.
Этот же порядок дает ответ на возможный вопрос, почему в ORDER BY нужно использовать псевдонимы из SELECT, а в WHERE эти же псевдонимы использовать еще нельзя.
Ошибка? Это не ошибка, это системная функция.