8.х Левое соединиение

Тема в разделе "Общие вопросы "1С:Предприятие 8"", создана пользователем Павел, 23 янв 2008.

  1. TopicStarter Overlay
    Павел
    Offline

    Павел

    Регистрация:
    28 сен 2007
    Сообщения:
    20
    Симпатии:
    0
    Баллы:
    1
    Недавно в книге наткнулся на определение Левое соединиение. До меня не дошло.

    Может ли кто-нибудь объянить подробно или может есть ссылка по данному вопросу?
  2. lazy
    Offline

    lazy Модераторы Команда форума Модератор

    Регистрация:
    1 сен 2007
    Сообщения:
    2.127
    Симпатии:
    4
    Баллы:
    29
    Язык запросов не такая штука, которую по книгам можно изучить. Тут опыт нужен. Хорошие примеры я видел в методичке "Использование запросов в системе 1С:Предприятие 8.0" маленькая методичка на 50 стр. но для изучающего вещь не заменимая. Есть в электронном варианте. Весит около 3,5 мб.
  3. vlashi
    Offline

    vlashi Опытный в 1С

    Регистрация:
    18 янв 2008
    Сообщения:
    143
    Симпатии:
    0
    Баллы:
    26
    Где есть в электронном виде?
  4. BabySG
    Offline

    BabySG Администраторы Команда форума Администратор

    Регистрация:
    10 июн 2007
    Сообщения:
    11.853
    Симпатии:
    12
    Баллы:
    29
    1. www.sql.ru
    2. Более простой варант - справка в Access, читать по SQL все, что относиться в SELECT...
  5. TopicStarter Overlay
    Павел
    Offline

    Павел

    Регистрация:
    28 сен 2007
    Сообщения:
    20
    Симпатии:
    0
    Баллы:
    1

    Можешь выложить на какой-нибудь файлопомойке? Или может адресок скажешь откуда скачать можно?
  6. lazy
    Offline

    lazy Модераторы Команда форума Модератор

    Регистрация:
    1 сен 2007
    Сообщения:
    2.127
    Симпатии:
    4
    Баллы:
    29
    Мужики, что за детский сад? Первая же страница поиска в яндексе выдает ссылки на скачивание.

    Вот например:
    http://ealexx.ifolder.ru/2986918

    ссылку не проверял :p
  7. Pasha
    Offline

    Pasha Опытный в 1С

    Регистрация:
    25 авг 2007
    Сообщения:
    65
    Симпатии:
    0
    Баллы:
    26
    ну по этой методичке точно нельзя учить SQL. Ну никак нельзя!
    Я бы взял MS Access, и с ним бы поэкспериментировал бы.
    Из каких соображений:
    В нем представлена "чистая" СУБД, без условностей 1С. И без сложностей, связанных с представлением в удобоваримом для обучаемого виде данных. То есть тупо создал две простейшие таблицы, сразу их можно видеть, править, реконструировать. Потом пытаться из связывать, сразу просматривая результат и параллельно почитывая встроенную справку.
    В 1С всетаки таблицы убраны глубоковато, не они главные объекты, а документы. Некоторые разночтения (ну пойди догадайся, что "реквизит" - это просто обыкновенное поле) тоже имеют место.

    А по поводу LEFT JOIN - это когда из двух таблиц (справочников??? регистров???? - да таблицы это все!) отбираются данные, причем эти данные сязаны по определенным полям (это когда справочники со ссылками, типа что товар - портвейн (спр "товары") и меряется он в бутылках(это справочник "ед_изм"), и из левой таблицы отбирается все товары подряд, а из правой только те, которые имеют связь с первой таблицей. Если не применять такую связь, то товары, не поименнованные размерностью, не попадут в список товаров, и соответственно, не отразятся.

    вот есть две таблицы

    Код:
    таблица "товар"
    code    name    md
    1    мыло    1
    2    веревка    3
    3    портвейн    2
    4    гвозди    0
    
    
    
    и таблица
    "ед_изм"
    Код:
    code    name
    1    кусок
    2    бутыль
    3    метр
    
    
    
    и если мы напишем запрос

    Код:
    SELECT Товар.name, ед_изм.name
    FROM Товар INNER JOIN ед_изм ON Товар.md = ед_изм.code;
    
    
    
    то получим

    Код:
    Товар.name    ед_изм.name
    мыло                         кусок
    веревка                     метр
    портвейн                     бутыль
    
    
    
    гвозди у нас не образмерены и не включились в таблицу-результат,
    а если мы напишем

    Код:
    SELECT Товар.name, ед_изм.name
    FROM 
    Товар LEFT JOIN ед_изм ON Товар.md = ед_изм.code;
    
    
    
    То отразится весь список товаров:

    Код:
    Товар.name    ед_изм.name
    мыло                     кусок
    веревка                     метр
    портвейн                     бутыль
    гвозди                     (а вот здесь будет пустая клетка - нулль)
    
    
    

    Короче, надо пробовать на реальной задаче. Но, опыт показывает, что в такие SQL-дебри лезут только ораклисты, да и то, только с целью загнуть пальцы перед коллегой. Мол, я более крутой девелопер, у меня семь вложений в предложении SELECT.

    ---
    Пример слеплен на Ассессе, соответственно, синтаксис не 1Сный, не бейте ногами :unsure:
  8. BabySG
    Offline

    BabySG Администраторы Команда форума Администратор

    Регистрация:
    10 июн 2007
    Сообщения:
    11.853
    Симпатии:
    12
    Баллы:
    29
    Ну, насчет "оракалистов" (слово-то какое! :unsure:) Вы зря, вот пример запроса, который однажды мне понадобился (автор не я):

    Код:
    ВЫБРАТЬ
    ПартииТоваровНаСкладахОстаткиИОбороты.Номенклатура               КАК Номенклатура,
    ПартииТоваровНаСкладахОстаткиИОбороты.ХарактеристикаНоменклатуры КАК ХарактеристикаНоменклатуры,
    ПартииТоваровНаСкладахОстаткиИОбороты.Склад                      КАК Склад,
    СУММА(
    ВЫБОР
    КОГДА ПартииТоваровНаСкладахОстаткиИОбороты.Период = НАЧАЛОПЕРИОДА(&КонПериода, День) ТОГДА
    ВЫБОР
    КОГДА ПартииТоваровНаСкладахОстаткиИОбороты.КоличествоКонечныйОстатокПредыдущий > 0 ТОГДА
    ВЫБОР
    КОГДА ПартииТоваровНаСкладахОстаткиИОбороты.КоличествоКонечныйОстаток <= 0 ТОГДА
    РАЗНОСТЬДАТ(ПартииТоваровНаСкладахОстаткиИОбороты.ПредыдущийПериод, ПартииТоваровНаСкладахОстаткиИОбороты.Период, ДЕНЬ)
    ИНАЧЕ
    РАЗНОСТЬДАТ(ПартииТоваровНаСкладахОстаткиИОбороты.ПредыдущийПериод, &КонПериода, ДЕНЬ) + 1
    КОНЕЦ
    ИНАЧЕ                            
    ВЫБОР 
    КОГДА ПартииТоваровНаСкладахОстаткиИОбороты.КоличествоКонечныйОстаток > 0 ТОГДА
    РАЗНОСТЬДАТ(ПартииТоваровНаСкладахОстаткиИОбороты.Период, &КонПериода, ДЕНЬ) + 1
    ИНАЧЕ
    0
    КОНЕЦ
    КОНЕЦ
    ИНАЧЕ
    ВЫБОР
    КОГДА ПартииТоваровНаСкладахОстаткиИОбороты.КоличествоКонечныйОстатокПредыдущий > 0 ТОГДА
    РАЗНОСТЬДАТ(ПартииТоваровНаСкладахОстаткиИОбороты.ПредыдущийПериод, ПартииТоваровНаСкладахОстаткиИОбороты.Период, ДЕНЬ)
    ИНАЧЕ
    0
    КОНЕЦ
    КОНЕЦ) КАК КоличествоДнейНаСкладе
    ИЗ
    (ВЫБРАТЬ 
    ТаблицаПредыдущиеПериоды.Номенклатура                                      КАК Номенклатура,
    ТаблицаПредыдущиеПериоды.ХарактеристикаНоменклатуры                        КАК ХарактеристикаНоменклатуры,
    ТаблицаПредыдущиеПериоды.Склад                                             КАК Склад,
    ТаблицаПредыдущиеПериоды.Период                                            КАК Период,
    ТаблицаПредыдущиеПериоды.КоличествоКонечныйОстаток                         КАК КоличествоКонечныйОстаток,
    ТаблицаПредыдущиеПериоды.ПредыдущийПериод                                  КАК ПредыдущийПериод,
    ПартииТоваровНаСкладахОстаткиИОборотыПредыдущие.КоличествоКонечныйОстаток  КАК КоличествоКонечныйОстатокПредыдущий
    ИЗ
    (   ВЫБРАТЬ
    ПартииТоваровНаСкладахОстаткиИОбороты1.Номенклатура               КАК Номенклатура,
    ПартииТоваровНаСкладахОстаткиИОбороты1.ХарактеристикаНоменклатуры КАК ХарактеристикаНоменклатуры,
    ПартииТоваровНаСкладахОстаткиИОбороты1.Склад                      КАК Склад,
    ПартииТоваровНаСкладахОстаткиИОбороты1.Период                     КАК Период,
    ПартииТоваровНаСкладахОстаткиИОбороты1.КоличествоКонечныйОстаток  КАК КоличествоКонечныйОстаток,
    МАКСИМУМ(ПартииТоваровНаСкладахОстаткиИОбороты2.Период)           КАК ПредыдущийПериод
    ИЗ
    РегистрНакопления.ПартииТоваровНаСкладах.ОстаткиИОбороты(&НачПериода, &КонПериода, День, , Номенклатура В ИЕРАРХИИ  (&Номенклатура)) КАК ПартииТоваровНаСкладахОстаткиИОбороты1
    ЛЕВОЕ СОЕДИНЕНИЕ 
    РегистрНакопления.ПартииТоваровНаСкладах.ОстаткиИОбороты(&НачПериода, &КонПериода, День, , Номенклатура В ИЕРАРХИИ  (&Номенклатура)) КАК ПартииТоваровНаСкладахОстаткиИОбороты2
    ПО (ИСТИНА)
    И ПартииТоваровНаСкладахОстаткиИОбороты1.Номенклатура               = ПартииТоваровНаСкладахОстаткиИОбороты2.Номенклатура
    И ПартииТоваровНаСкладахОстаткиИОбороты1.ХарактеристикаНоменклатуры = ПартииТоваровНаСкладахОстаткиИОбороты2.ХарактеристикаНоменклатуры
    И ПартииТоваровНаСкладахОстаткиИОбороты1.Склад                      = ПартииТоваровНаСкладахОстаткиИОбороты2.Склад
    И ПартииТоваровНаСкладахОстаткиИОбороты1.Период > ПартииТоваровНаСкладахОстаткиИОбороты2.Период
    
    СГРУППИРОВАТЬ ПО
    ПартииТоваровНаСкладахОстаткиИОбороты1.Номенклатура,
    ПартииТоваровНаСкладахОстаткиИОбороты1.ХарактеристикаНоменклатуры,
    ПартииТоваровНаСкладахОстаткиИОбороты1.Склад,
    ПартииТоваровНаСкладахОстаткиИОбороты1.Период,
    ПартииТоваровНаСкладахОстаткиИОбороты1.КоличествоКонечныйОстаток
    ) КАК ТаблицаПредыдущиеПериоды
    
    ЛЕВОЕ СОЕДИНЕНИЕ 
    РегистрНакопления.ПартииТоваровНаСкладах.ОстаткиИОбороты(&НачПериода, &КонПериода, День, , Номенклатура В ИЕРАРХИИ  (&Номенклатура)) КАК ПартииТоваровНаСкладахОстаткиИОборотыПредыдущие
    
    ПО ИСТИНА
    И ТаблицаПредыдущиеПериоды.Номенклатура               = ПартииТоваровНаСкладахОстаткиИОборотыПредыдущие.Номенклатура
    И ТаблицаПредыдущиеПериоды.ХарактеристикаНоменклатуры = ПартииТоваровНаСкладахОстаткиИОборотыПредыдущие.ХарактеристикаНоменклатуры
    И ТаблицаПредыдущиеПериоды.Склад                      = ПартииТоваровНаСкладахОстаткиИОборотыПредыдущие.Склад
    И ТаблицаПредыдущиеПериоды.ПредыдущийПериод           = ПартииТоваровНаСкладахОстаткиИОборотыПредыдущие.Период
    ) КАК ПартииТоваровНаСкладахОстаткиИОбороты
    
    СГРУППИРОВАТЬ ПО
    ПартииТоваровНаСкладахОстаткиИОбороты.Номенклатура,
    ПартииТоваровНаСкладахОстаткиИОбороты.ХарактеристикаНоменклатуры,
    ПартииТоваровНаСкладахОстаткиИОбороты.Склад
    
    АВТОУПОРЯДОЧИВАНИЕ
  9. Pasha
    Offline

    Pasha Опытный в 1С

    Регистрация:
    25 авг 2007
    Сообщения:
    65
    Симпатии:
    0
    Баллы:
    26
    А я вот с такими монстроподобными запросами решил бороться иначе: писать параллельные регистры накопления, узкоспециализированные ИЗНАЧАЛЬНО. Тогда остается только отобрать диапазон дат и все готово.
    Хотя чего только в жизни не бывает.
    Но, есть подозрение, что это чудо - результат работы генератора запроса, там ведь ограничений нет никаких.
    ---
    А вообще, курс молодого бойца по SQL на данном Уважаемом ресурсе очень даже бы и не помешал.
  10. BabySG
    Offline

    BabySG Администраторы Команда форума Администратор

    Регистрация:
    10 июн 2007
    Сообщения:
    11.853
    Симпатии:
    12
    Баллы:
    29
    На самом деле - это труд одного уважаемого человека.
    Требовалось получить запросом общее количество дней наличия товара на складе в заданном периоде с группировками:
    Номенклатура, ХарактеристикаНоменклатуры, Склад.

    Днем наличия товара считается день, на конец которого остаток положительный.

    Если Вы готовы взять на себя сей почетный труд - только будем рады, ибо всем сразу не успеваешь заняться... Очень много идей - но за всеми не успеть - еще работать надо :) По мере возможности добавляем новые ресурсы и удобства на форуме.
  11. Devdred
    Offline

    Devdred

    Регистрация:
    20 янв 2008
    Сообщения:
    17
    Симпатии:
    0
    Баллы:
    1
    Привет всем. Чтото уходите от темы. Внесу свои пять копеек.

    Незнаю как в MS Access но в 1С левое соединение на старых версиях восьмерки работало по другому :unsure: в общем то в случае примера как у Pasha оно так и будет работать :D а вот если чуть чуть поменяем таблицы в нижней таблице будет еще одна запись
    Первая таблица
    Код:
    code    name    md
    1    мыло    1
    2    веревка    3
    3    портвейн    2
    4    гвозди    0
    
    
    Вторая таблица
    Код:
    code    name
    1    кусок
    2    бутыль
    3    метр
    3    километр
    
    
    то при использовании запроса
    Код:
    |Выбрать
    | таб.name
    | таб1.name
    | ИЗ
    |  Справочник.таб КАК таб
    | ЛЕВОЕ СОЕДИНЕНИЕ Справочник.таб1 КАК таб1
    | ПО таб.md = таб1.code
    
    
    то выдаст следующее B)
    Код:
    мыло    кусок
    веревка   метр
    веревка   километр
    портвейн   бутыль
    гвозди  NULL
    
    
    Вот даже и не знаю как всетаки правильней но мне при переходе на новые версии пришлось переписывать кучу старых запросов :D добавляя различные условия...
  12. BabySG
    Offline

    BabySG Администраторы Команда форума Администратор

    Регистрация:
    10 июн 2007
    Сообщения:
    11.853
    Симпатии:
    12
    Баллы:
    29
    Devdred,
    Дык, собственно, так и должно быть... 8.0.6 работает также, как и 8.1.10 - поскольку недавно переводил :)
  13. Devdred
    Offline

    Devdred

    Регистрация:
    20 янв 2008
    Сообщения:
    17
    Симпатии:
    0
    Баллы:
    1
    А давно это было B) по моему 8.0.4 (может 8.0.1.4 :D) это когда кроме управление персоналом да торговли ничего небыло, брал чтоб разобраться что к чему :unsure: бухия еще у них в проекте была.
    Вообще мне думается что так должно работать правое соединение или полное соеденинеие кажись логичней
  14. suspender
    Offline

    suspender

    Регистрация:
    7 апр 2008
    Сообщения:
    1
    Симпатии:
    0
    Баллы:
    1
    Сейчас с удивлением обнаружил, что в 8.0.13 left join работает также как и inner join.
    Сначала заметил что тупят некоторые мои самописные отчёты, потом вырожденную ситуацию проверил:
    Код:
    ВЫБРАТЬ
    РеализацияТоваровУслуг.Ссылка,
    СчетФактураВыданный.Ссылка КАК Ссылка1
    ИЗ
    Документ.РеализацияТоваровУслуг КАК РеализацияТоваровУслуг
    Левое СОЕДИНЕНИЕ Документ.СчетФактураВыданный КАК СчетФактураВыданный
    ПО РеализацияТоваровУслуг.Ссылка = СчетФактураВыданный.ДокументОснование
    ГДЕ
    СчетФактураВыданный.Проведен = ИСТИНА
    
    
    
    
    При условии что Реализация в природе существует, а СчётФактуры либо нет, либо непроведена - на выходе получется НИЧЕГО. Хотя по идее должны иметь на выходе ссылку на реализацию и пустоту во 2-м столбце.
    Это баг или фича ?

    Конфа : сильно переработанная УТ 10.2, хотя это тут не важно

    Edited:
    Мде, 3 часа тупил, стоило написать в форум - сразу понял всё. В общем условие применяется к результату целиком а не к леводжойнящейся таблице

    Код:
    ВЫБРАТЬ
    РеализацияТоваровУслуг.Ссылка,
    ПроведённыеСчётФактуры.Ссылка КАК Ссылка1
    ИЗ
    Документ.РеализацияТоваровУслуг КАК РеализацияТоваровУслуг
    ЛЕВОЕ СОЕДИНЕНИЕ (ВЫБРАТЬ
    СчетФактураВыданный.Ссылка КАК Ссылка
    ИЗ
    Документ.СчетФактураВыданный КАК СчетФактураВыданный
    ГДЕ
    СчетФактураВыданный.Проведен = ИСТИНА) КАК ПроведённыеСчётФактуры
    ПО РеализацияТоваровУслуг.Ссылка = ПроведённыеСчётФактуры.Ссылка.ДокументОснование.Ссылка
    
    
    
    Вот такое отрабатывает так как мне и надо.

    ps. Всегда считал что условие в запросах с левым соединениям, если затрагивает только одну из таблиц - к ней и применяется (независимо от СУБД считал).

Поделиться этой страницей