В новом синтаксисе ABAP SQL появилась возможность прописывать условия для таблиц LEFT JOIN в WHERE.
Однако есть существенное отличие между условием прописанным после ON и в условии WHERE.
Сначала посмотрим, что у нас выберется из таблиц MSPR И VEPO без дополнительных ограничений:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
"Запрос 1 DATA ltd_table_all_1 TYPE TABLE OF lty_s_table_all. SELECT mspr~werks, mspr~lgort, mspr~matnr, mspr~charg, vepo~vbeln, vepo~sobkz FROM mspr LEFT JOIN vepo ON vepo~matnr = mspr~matnr AND vepo~werks = mspr~werks AND vepo~lgort = mspr~lgort AND vepo~charg = mspr~charg INTO CORRESPONDING FIELDS OF TABLE @ltd_table_all_1 WHERE mspr~matnr = '000000001300000160' AND mspr~lgort = '6101' AND mspr~werks = '3100' . |
Мы видим, что для партии "0000004239" значение в таблице vepo не найдено вообще. Для партий "0000004226", "0000004233", "0000004237", "0000004460" существуют записи в VEPO с пустым значением поля SOBKZ.
Теперь сделаем дополнительное ограничение по VEPO-SOBKZ , при этом из MSPR выбираем все строки, что и раньше. Но из VEPO выбираем только записи с SOBKZ = 'Q'.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
" Запрос 2 DATA ltd_table_all_2 TYPE TABLE OF lty_s_table_all. SELECT mspr~werks, mspr~lgort, mspr~matnr, mspr~charg, vepo~vbeln, vepo~sobkz FROM mspr LEFT JOIN vepo ON vepo~matnr = mspr~matnr AND vepo~sobkz = 'Q' AND vepo~werks = mspr~werks AND vepo~lgort = mspr~lgort AND vepo~charg = mspr~charg INTO CORRESPONDING FIELDS OF TABLE @ltd_table_all_2 WHERE mspr~matnr = '000000001300000160' AND mspr~lgort = '6101' AND mspr~werks = '3100' |
В полученном результате для партий "0000004237", "0000004233" мы не нашли записи в VEPO и эти строки вышли с пустым VBELN. Все как и в старом синтаксисе.
Попробуем перенести условие SOBKZ = 'Q' в WHERE.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
" Запрос 3 DATA ltd_table_all_3 TYPE TABLE OF lty_s_table_all. SELECT mspr~werks, mspr~lgort, mspr~matnr, mspr~charg, vepo~vbeln, vepo~sobkz FROM mspr LEFT JOIN vepo ON vepo~matnr = mspr~matnr AND vepo~werks = mspr~werks AND vepo~lgort = mspr~lgort AND vepo~charg = mspr~charg INTO CORRESPONDING FIELDS OF TABLE @ltd_table_all_3 WHERE mspr~matnr = '000000001300000160' AND mspr~lgort = '6101' AND mspr~werks = '3100' AND vepo~sobkz = 'Q' . |
И мы увидим, что на выходе остались только строки с SOBKZ = 'Q'.
Как же так?
Все как всегда скрывается в хелпе)) Если мы ограничиваем результаты в WHERE, исключение значений происходит уже после LEFT JOIN. Т.е. сначала все отрабатывает как и в SELECT 1, но потом все строки с SOBKZ <> 'Q' удаляются из выборки.
Это надо учитывать при конструировании SELECT, иначе, если он будет более сложный чем в примерах выше, можем получить вообще слабопрогнозируемые результаты.