Автор Тема: Сложный SELECT  (Прочитано 29784 раз)

0 Пользователей и 1 Гость просматривают эту тему.

Оффлайн A.

  • Newbie
  • *
  • Сообщений: 110
  • Репутация: +1/-0
  • YearsYearsYearsYearsYearsYearsYearsYearsYearsYearsYearsYearsYearsYearsYears
Сложный SELECT
« : Сентябрь 24, 2012, 04:18:22 pm »
Добрый день.

Есть сложный SELECT, который содержит множество JOIN-ов - как INNER, так и OUTER. Структура у него следующая:

Код: You are not allowed to view links. Register or Login
SELECT DISTINCT <поля для выбора>
    APPENDING CORRESPONDING FIELDS OF TABLE gt_itab
    FROM table_1
    INNER JOIN table_2 ON
      table_1~field_1 = table_2~field_1 AND
      table_1~field_2 = table_2~field_2
    INNER JOIN table_3 ON
      table_1~field_1 = table_3~field_1 AND
      table_1~field_2 = table_3~field_2 AND
      table_1~field_3 = table_3~field_3
    INNER JOIN table_4 ON
      table_1~field_5 = table_4~field_5
    LEFT OUTER JOIN table_5 ON
      table_1~field_6 = table_5~field_6
    LEFT OUTER JOIN table_6 ON
      table_1~field_7 = table_6~field_7
    LEFT OUTER JOIN table_7 ON
      table_1~field_8 = table_7~field_8 AND
      table_1~field_9 = table_7~field_9
    WHERE table_5~field_10   =  'ABC'
      AND table_5~field_11  >= 'DEF'
      AND table_3~field_1 IN so_fld_1
      AND table_3~field_2 IN so_fld_2
      AND table_1~field_12 IN so_fld_12
      AND table_1~field_13 IN so_fld_13.

Если в SE11 задать для table_1 критерии, указанные в условии WHERE, то не выбирается никаких данных. Однако, в результирующей внутренней таблице заполняются поля из этой таблицы! Как так происходит? Условие отбрасывается из-за наличия LEFT JOIN-а? Какие действия нужно выполнить с помощью SE11, чтобы выйти на те значения, что получаются во внутренней таблице?

Оффлайн A.

  • Newbie
  • *
  • Сообщений: 110
  • Репутация: +1/-0
  • YearsYearsYearsYearsYearsYearsYearsYearsYearsYearsYearsYearsYearsYearsYears
Re: Сложный SELECT
« Ответ #1 : Сентябрь 24, 2012, 04:22:33 pm »
Дополнение: по условиям в WHERE для таблиц table_3 и table_5 данные выбираются. Но связывание всех таблиц в этом SELECT-е производится по таблице table_1.

Оффлайн A.

  • Newbie
  • *
  • Сообщений: 110
  • Репутация: +1/-0
  • YearsYearsYearsYearsYearsYearsYearsYearsYearsYearsYearsYearsYearsYearsYears
Re: Сложный SELECT
« Ответ #2 : Сентябрь 24, 2012, 04:42:36 pm »
Вообще, как работают JOIN-ы? Сначала данные выбираются из всех таблиц, связываются и фильтруются? Или как-то иначе?

Оффлайн Uukrul

  • SAP ECC 6.0 Ehp(*)
  • Administrator
  • Epic Member
  • *****
  • Сообщений: 3 809
  • Репутация: +47/-0
  • Пол: Мужской
  • YearsYearsYearsYearsYearsYearsYearsYearsYearsYearsYearsYearsYearsYearsYearsYearsYears
    • Sapforum.BIZ
Re: Сложный SELECT
« Ответ #3 : Сентябрь 24, 2012, 05:13:42 pm »
You are not allowed to view links. Register or Login
Вообще, как работают JOIN-ы?
Чуть позже отпишусь.

Оффлайн A.

  • Newbie
  • *
  • Сообщений: 110
  • Репутация: +1/-0
  • YearsYearsYearsYearsYearsYearsYearsYearsYearsYearsYearsYearsYearsYearsYears
Re: Сложный SELECT
« Ответ #4 : Сентябрь 24, 2012, 09:41:04 pm »
Было бы неплохо, т.к. осмотр плана запроса ясности не внёс.

Оффлайн Uukrul

  • SAP ECC 6.0 Ehp(*)
  • Administrator
  • Epic Member
  • *****
  • Сообщений: 3 809
  • Репутация: +47/-0
  • Пол: Мужской
  • YearsYearsYearsYearsYearsYearsYearsYearsYearsYearsYearsYearsYearsYearsYearsYearsYears
    • Sapforum.BIZ
Re: Сложный SELECT
« Ответ #5 : Сентябрь 25, 2012, 01:41:40 am »
Значит так, для начала кто есть кто из команд. Как я понимаю с точки зрения OpenSQL:

INNER JOIN = JOIN
LEFT OUTER JOIN = LEFT JOIN

т.е. INNER и OUTER можно в принципе не использовать, так как просто JOIN это всегда INNER, а LEFT JOIN это всегда LEFT OUTER JOIN.

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

Теперь как вся эта кухня работает, опять же только мои мысли, если что-то скажу не так, ну значит ошибся. И так имеем соединение таблиц, используя команду JOIN (от же INNER JOIN), система, выполняет по заданному условию JOIN <…> ON <…>, объединение двух таблиц. При этом, если для какой-то из записей при объединения нет соответствия в соседней таблице, то такие записи удаляются, т.е. считается что объединение не произошло, т.е например есть две таблицы со следующими записями:

Пример объединения таблиц по полям WERKS и LGORT

Таблица: TABLE_ONE (Поля в таблице: WERKS. LGORT, TEXT)
1000 0001 Test
1000 0002 Test
1000 0003 Test
1000 0004 Test
1000 0005 Test

Таблица: TABLE_TWO (Поля в таблице: WERKS. LGORT, TEXT)
1000 0002 Test
1000 0005 Test
1000 0007 Test

Система выполнит объединение и получит сначала следующую таблицу
Код: You are not allowed to view links. Register or Login
1. 1000 0001 Test
2. 1000 0002 Test = 1000 0002 Test
3. 1000 0003 Test
4. 1000 0004 Test
5. 1000 0005 Test = 1000 0005 Test
6.                = 1000 0007 Test

Теперь произойдет удаление записей 1, 3, 5 и 6 так как для этих записей нет соответствия друг другу, а после этого выполнится применение условия отбора для записей 2 и 5 по условию указанному после WHERE соответственно задав, например склад TABLE_TWO~LGORT = «0005» записи будут выбраны, точнее будет выбрана одна запись 5. Для склада 0004 соответственно система скажет, что записей в выборе нет.

Теперь сделаем объединение таблиц, используя соединение LEFT JOIN (оно же LEFT OUTER JOIN). Произойдет такое же объединение таблиц? как и случае с INNER, но после объединения будут удалены только записи таблицы TABLE_TWO, которые не имеют соответствия в таблице TABLE_ONE, т.е. результирующий набор будет иметь в своем составе записи с 1 по 5, после чего на эту таблицу будет наложено условие, заданное в WHERE, т.е. соответственно если ограничение будет по складу TABLE_TWO~LGORT = «0005», то будет выбрана одна запись, а если там будет задан склад «0007», то соответственно ничего не будет выбрано, так как записи с таким складом после выполнения объединения в полученном наборе не будет.

Вывод раз: Сначала идет объединения таблиц указанных в запросе и только потом на результирующий набор накладывается условие WHERE. Объединение идет согласно заданным правилам т.е. или INNER или LEFT.

Вывод два: Так как OpenSQL это не совсем те SQL-ли которые есть в разных базах, т.е. это какое-то среднее звено, со своими ограничениями, т.е. например нельзя в ограничениях WHERE указать значения по таблице которая соединяется через LEFT JOIN, ну по крайней мере у меня говорит что: No fields from the right-hand table of a LEFT OUTER JOIN may appear in the WHERE condition: "FOUR~LGORT", т.е. таблица которая соединена через LEFT не разрешает использовать свои поля в условии отбора WHERE, поэтому как у вас получилось задать для LEFT OUTER JOIN table_5 использовать поля пятой таблицы в WHERE table_5~field_10  =  'ABC' у меня так не выходило ограничивать объединение.


PS: Ну типа такие мысли. Если кто может поправить, пишем…

Оффлайн A.

  • Newbie
  • *
  • Сообщений: 110
  • Репутация: +1/-0
  • YearsYearsYearsYearsYearsYearsYearsYearsYearsYearsYearsYearsYearsYearsYears
Re: Сложный SELECT
« Ответ #6 : Сентябрь 25, 2012, 10:19:07 am »
Вот полный код запроса:

Код: You are not allowed to view links. Register or Login
  SELECT DISTINCT
         tab_1~fld_1 tab_1~fld_2 tab_1~fld_3 tab_1~fld_4 tab_1~fld_5 tab_1~fld_6 tab_1~fld_7 tab_1~fld_8 tab_1~fld_9 tab_1~fld_10 tab_1~fld_11 tab_1~fld_12 tab_1~fld_13 tab_1~fld_14 tab_1~fld_15 tab_1~fld_16 tab_1~fld_17
         tab_2~fld_18 tab_2~fld_19 tab_2~fld_20 tab_2~fld_21 tab_2~fld_22 tab_2~fld_23 tab_2~fld_24 tab_2~fld_25
         tab_3~fld_26 tab_3~fld_27 tab_3~fld_28 tab_3~fld_29 tab_3~fld_30 tab_3~fld_31 tab_3~fld_29
         tab_4~fld_32 tab_4~fld_33 tab_4~fld_34 tab_4~fld_35
         tab_5~fld_28 tab_5~fld_36 tab_1~fld_37
         tab_6~fld_38
         tab_7~fld_39 tab_7~fld_40
         tab_8~fld_41 tab_8~fld_42 tab_8~fld_43 tab_8~fld_44
         tab_9~fld_45 tab_9~fld_46 tab_9~fld_47 tab_9~fld_48 tab_9~fld_49 tab_9~fld_50 tab_9~fld_51 tab_9~fld_52 tab_9~fld_53
    APPENDING CORRESPONDING FIELDS OF TABLE gt_itab
    FROM tab_1
    INNER JOIN tab_2 ON
      tab_1~fld_1 = tab_2~fld_1 AND
      tab_1~fld_2 = tab_2~fld_2 AND
      tab_1~fld_3 = tab_2~fld_3 AND
      tab_1~fld_4 = tab_2~fld_4
    INNER JOIN tab_3 ON
      tab_1~fld_1 = tab_3~fld_1 AND
      tab_1~fld_2 = tab_3~fld_2 AND
      tab_1~fld_3 = tab_3~fld_3
    INNER JOIN tab_4 ON
      tab_1~fld_55 = tab_4~fld_55
    INNER JOIN tab_5 ON
      tab_1~fld_8 = tab_5~fld_56
    LEFT OUTER JOIN tab_6 ON
      tab_1~fld_37 = tab_6~fld_37
    LEFT OUTER JOIN tab_7 ON
      tab_1~fld_14 = tab_7~fld_14
    LEFT OUTER JOIN tab_8 ON
      tab_1~fld_55 = tab_8~fld_55 AND
      tab_1~fld_17 = tab_8~fld_17
    LEFT OUTER JOIN tab_9 ON
      tab_1~fld_1 = tab_9~fld_1 AND
      tab_1~fld_2 = tab_9~fld_2 AND
      tab_1~fld_3 = tab_9~fld_3
    WHERE tab_5~fld_40   =  'R'
      AND tab_5~fld_58  >= sy-datum
      AND tab_3~fld_1      IN s_fld_1
      AND tab_3~fld_2      IN s_fld_2
      AND tab_3~fld_26      IN s_fld_26
      AND tab_1~fld_6      IN so_fld_6
      AND tab_1~fld_8      IN s_fld_8
      AND tab_1~fld_37      IN s_fld_37
      AND tab_4~fld_55      IN s_fld_55.

Про то, что нельзя использовать поля правой таблицы при соединении LEFT, я в курсе, просто на скорую руку склепал запрос.

Про то, как соединяются две таблицы, понятно. А когда таблиц 9, как в моём случае, в какой последовательности идет выбор данных и последующие их соединения и фильтрация? Я посмотрел план запроса, сначала идет выбор из tab_2, потом tab_1, затем tab_9, и т.д. Логика неясна. В другой системе с этим же запросом план показывает сначала tab_3, tab_1, tab_9, и т.д. - то есть по-другому.

Оффлайн Uukrul

  • SAP ECC 6.0 Ehp(*)
  • Administrator
  • Epic Member
  • *****
  • Сообщений: 3 809
  • Репутация: +47/-0
  • Пол: Мужской
  • YearsYearsYearsYearsYearsYearsYearsYearsYearsYearsYearsYearsYearsYearsYearsYearsYears
    • Sapforum.BIZ
Re: Сложный SELECT
« Ответ #7 : Сентябрь 25, 2012, 12:03:13 pm »
You are not allowed to view links. Register or Login
Про то, как соединяются две таблицы, понятно. А когда таблиц 9, как в моём случае, в какой последовательности идет выбор данных и последующие их соединения и фильтрация? Я посмотрел план запроса, сначала идет выбор из tab_2, потом tab_1, затем tab_9, и т.д. Логика неясна. В другой системе с этим же запросом план показывает сначала tab_3, tab_1, tab_9, и т.д. - то есть по-другому.
Ну тут как бы ситуация тоже ясна, во-первых, с точки зрения работы без оптимизации понятно, что мы соединяем все таблицы по INNER не важно в каком прядке, главное потом то, что останутся записи присутствующие во всех объединенных таблицах, но так как у нас есть оптимизатор, то по бытовой логике я бы читал сначала таблицы с лучшей статистикой и меньшим объемом данных, потому что если имеем два таблицы в которых в одной 100 записей, а в другой 10, то я бы прочитал сначала ту в которой 10 и уже ее бы соединял бы с большей таблицей, так как в этом случае мне бы пришлось по максимуму из второй таблицы тоже прочитать всего 10 записей а не все 100, по полям объединения. Поэтому тут как говорится оптимизатору виднее, в каком порядке требуется читать данные из таблиц в условии INNER. Ну а  с таблицами соединенными по LEFT опять же оптимизатор сам тоже решает в какой момент и какую из них подгрузить для результирующей выборки. Вообще я не знаю что за база у вас лежит внизу SAP.

Оффлайн A.

  • Newbie
  • *
  • Сообщений: 110
  • Репутация: +1/-0
  • YearsYearsYearsYearsYearsYearsYearsYearsYearsYearsYearsYearsYearsYearsYears
Re: Сложный SELECT
« Ответ #8 : Сентябрь 25, 2012, 01:36:20 pm »
Если предположить, что сначала формируется результат работы всех INNER JOIN, то что будет, если к этому результату будет добавлена таблица с условием LEFT JOIN? Выберутся все записи из таблицы справа от LEFT JOIN (см. SE38, DEMO_JOINS, "demo2 OUTER JOIN demo1")?

Потом, конкретно в моём случае, в SE11 по условию в WHERE из таблицы tab_1 не было выбрано ни одной записи, однако же в результирующей внутренней таблице gt_itab содержатся данные из соответствующих полей этой таблицы! Как так? Какая логика в работе?

P.S. БД - Оракл.

Оффлайн Uukrul

  • SAP ECC 6.0 Ehp(*)
  • Administrator
  • Epic Member
  • *****
  • Сообщений: 3 809
  • Репутация: +47/-0
  • Пол: Мужской
  • YearsYearsYearsYearsYearsYearsYearsYearsYearsYearsYearsYearsYearsYearsYearsYearsYears
    • Sapforum.BIZ
Re: Сложный SELECT
« Ответ #9 : Сентябрь 25, 2012, 01:46:56 pm »
You are not allowed to view links. Register or Login
Если предположить, что сначала формируется результат работы всех INNER JOIN, то что будет, если к этому результату будет добавлена таблица с условием LEFT JOIN? Выберутся все записи из таблицы справа от LEFT JOIN (см. SE38, DEMO_JOINS, "demo2 OUTER JOIN demo1")?

Потом, конкретно в моём случае, в SE11 по условию в WHERE из таблицы tab_1 не было выбрано ни одной записи, однако же в результирующей внутренней таблице gt_itab содержатся данные из соответствующих полей этой таблицы! Как так? Какая логика в работе?
Ну из плана запроса,таблица 9 у вас выбирается третьей, значит оно все таки по каким-то своим условиям и правилам объединяет таблицу 2 или 3 с таблицей 1, а потом к этому результату доопределяет данные таблицы 9. Вообще-то там можно использовать скобки как я понимаю для определения порядка объединения таблиц. А далее еще надо похоже читать как оракловая база работает с соединениями таблиц. Я так понял таблицы у вас для примера приведены, т.е. реальный запрос немного другой, так что проверить его на моих данных и базе DB6 не получится. Вообще-то я в кодах системы сложные объединения не встречал практически, сам обычно более чем основная таблица + пяток вспомогательных справочных не объединял.

PS: Кстати где почитать как система работает с базой данных и как это передается на уровень базы с уровня SAP ABAP-а, не подскажу, я статьи на такие темы не встречал к сожалению  :-\

Оффлайн A.

  • Newbie
  • *
  • Сообщений: 110
  • Репутация: +1/-0
  • YearsYearsYearsYearsYearsYearsYearsYearsYearsYearsYearsYearsYearsYearsYears
Re: Сложный SELECT
« Ответ #10 : Сентябрь 25, 2012, 02:14:10 pm »
Да вот я думаю, что не должно быть так, что результат работы селекта должен зависеть от типа БД и её оптимизатора. План запроса я посмотрел, дабы он как-то улёгся в логическую картину работы селекта, описанную в хелпе. Не улёгся.

Тут вопрос ещё такой возникает. Допустим, всю эту басню я хочу сделать отдельными SELECT во внутренние таблицы, а потом соединять их. Но! Если идти по порядку, и выбрать данные из tab_1, которых там нет по условию в WHERE, то к чему потом подклеивать остальные? Ни к чему, выходит. Тогда нужно брать другие таблицы, смотреть, есть ли в них данные по условиям в WHERE, и потом делать как бы наоборот - не от tab_1 плясать, когда её значения являются ключами для выбора из остальных таблиц, а значения в остальных таблицах являются ключами для выбора из tab_1.

Вот такие у меня нечётко пока оформившиеся размышления. Есть еще мысль про подобие пустой таблицы для FOR ALL ENTRIES, когда выбирается всё.

Оффлайн Uukrul

  • SAP ECC 6.0 Ehp(*)
  • Administrator
  • Epic Member
  • *****
  • Сообщений: 3 809
  • Репутация: +47/-0
  • Пол: Мужской
  • YearsYearsYearsYearsYearsYearsYearsYearsYearsYearsYearsYearsYearsYearsYearsYearsYears
    • Sapforum.BIZ
Re: Сложный SELECT
« Ответ #11 : Сентябрь 25, 2012, 02:19:27 pm »
You are not allowed to view links. Register or Login
Да вот я думаю, что не должно быть так, что результат работы селекта должен зависеть от типа БД и её оптимизатора.
Вот тут как раз есть варианты... так как SQL-база она у всех SQL-база в принципе, а вот дальше идут разночтения именно в оптимизаторах и то как они работают с таблицами. К примеру статистика индекса слетела или стала хуже и все, запрос который работал секунды, стал тупить по часу. И это только статистика индекса, которую в плане запроса сразу видно  :-\

Оффлайн Uukrul

  • SAP ECC 6.0 Ehp(*)
  • Administrator
  • Epic Member
  • *****
  • Сообщений: 3 809
  • Репутация: +47/-0
  • Пол: Мужской
  • YearsYearsYearsYearsYearsYearsYearsYearsYearsYearsYearsYearsYearsYearsYearsYearsYears
    • Sapforum.BIZ
Re: Сложный SELECT
« Ответ #12 : Сентябрь 25, 2012, 02:21:14 pm »
You are not allowed to view links. Register or Login
Вот такие у меня нечётко пока оформившиеся размышления. Есть еще мысль про подобие пустой таблицы для FOR ALL ENTRIES, когда выбирается всё.
Ну надеюсь как размышления дойдут до логического конца, напишешь о результатах  8)

Оффлайн A.

  • Newbie
  • *
  • Сообщений: 110
  • Репутация: +1/-0
  • YearsYearsYearsYearsYearsYearsYearsYearsYearsYearsYearsYearsYearsYearsYears
Re: Сложный SELECT
« Ответ #13 : Сентябрь 25, 2012, 02:29:17 pm »
Ну, если я додумаюсь, то непременно поделюсь.

Во всех курсах пишут, что Open SQL используется специально, чтобы абстрагироваться от технической реализации соответствующей БД с помощью DBMS. Поэтому по идее, основываясь на этой информации, ни тип БД, ни что иное влиять не должны на логику работы SELECT-а в программе.

Оффлайн Uukrul

  • SAP ECC 6.0 Ehp(*)
  • Administrator
  • Epic Member
  • *****
  • Сообщений: 3 809
  • Репутация: +47/-0
  • Пол: Мужской
  • YearsYearsYearsYearsYearsYearsYearsYearsYearsYearsYearsYearsYearsYearsYearsYearsYears
    • Sapforum.BIZ
Re: Сложный SELECT
« Ответ #14 : Сентябрь 25, 2012, 03:11:36 pm »
You are not allowed to view links. Register or Login
Во всех курсах пишут, что Open SQL используется специально, чтобы абстрагироваться от технической реализации соответствующей БД с помощью DBMS. Поэтому по идее, основываясь на этой информации, ни тип БД, ни что иное влиять не должны на логику работы SELECT-а в программе.
Ну, мне кажется, не путаем диалекты, т.е. конструкции языка, которые действительно не должны влиять от варианта используемой БД с техникой выбора данных, т.е. работой оптимизатора, который как раз зависит от БД, т..е. конструкция объединения, не зависит, а вот как работает само объединение таблиц, очень может быть, что могут быть варианты. И еще раз повторюсь, в программах SAP, я сложных запросов не встречал это что-то типа:
Код: You are not allowed to view links. Register or Login
SELECT * FROM equi
         INTO CORRESPONDING FIELDS OF TABLE lt_v_equi_iflos
         FOR ALL ENTRIES IN equnr
                WHERE equnr =  equnr-low
                AND   erdat      IN erdat
                AND   ernam      IN ernam
                AND   aedat      IN aedat
                AND   aenam      IN aenam
                AND   begru      IN begru
                AND   eqtyp      IN eqtyp
                AND   eqart      IN eqart
                AND   ansdt      IN ansdt
                AND   answt      IN answt
                AND   waers      IN waers
                AND   elief      IN elief
                AND   herst      IN herst
                AND   serge      IN serge
                AND   typbz      IN typbz
                AND   krfkz      LIKE krfkz
                AND   kmatn      IN kmatn
                AND   matnr      IN matnr
                AND   sernr      IN sernr
                AND   charge     IN charge
                AND   kunde      IN kunde
                AND   herld      IN herld
                AND   baujj      IN baujj
                AND   invnr      IN invnr
                AND   groes      IN groes
                AND   brgew      IN brgew
                AND   gewei      IN gewei
                AND   cuobj      IN r_cuobj
                AND   auldt      IN auldt
                AND   inbdt      IN inbdt
                AND   werk       IN werk
                AND   lager      IN lager
                AND   uii        IN gr_uii
                AND   (gt_where) .
где выборка идет по ракурсу БД, типа как на рисунке ниже. В самих программах, что-то типа проведенного запроса, не встречалось.

Оффлайн A.

  • Newbie
  • *
  • Сообщений: 110
  • Репутация: +1/-0
  • YearsYearsYearsYearsYearsYearsYearsYearsYearsYearsYearsYearsYearsYearsYears
Re: Сложный SELECT
« Ответ #15 : Декабрь 14, 2012, 05:00:20 pm »
Всем добрый вечер.

Подскажите, пожалуйста, по такому вопросу.

Есть выборка:

Код: You are not allowed to view links. Register or Login
select {поля таблицы 1}+{поле keyz1_k таблицы 2}
    into corresponding fields of table lt_tab
    from Таблица 1 as z
    left join Таблица 2 as t
      on z~keyz1 eq t~keyz1_k
    where z~budat in gr_date
      and z~bukrs eq p_bukrs.

Есть другая выборка:
Код: You are not allowed to view links. Register or Login
  select {поля таблицы 1}
    into corresponding fields of table lt_tab_tmp
    from Таблица_1
    where budat in gr_date and
          bukrs eq p_bukrs.

Как мне казалось, количество строк во внутренних таблицах lt_tab и lt_tab_tmp должно быть одинаково. Однако практика показывает иное.

Как я думал, при левом соединении сначала выбираются записи из основной таблицы (той, что слева от оператора LEFT), а затем к ним пристыковываются данные из второй таблицы (той, что справа), т.е. заполняются поля результирующей таблицы, если есть соответствующие данные. Но всё почему-то не так. Количество записей в каждой из выборок различается.

Согласно плану запроса, сначала выбираются данные из Таблицы 2, потом из Таблицы 1, а потом выполняется операция HASH JOIN RIGHT OUTER, и последней - операция FILTER (см. аттач).

Как это можно объяснить работу LEFT OUTER JOIN?

Оффлайн A.

  • Newbie
  • *
  • Сообщений: 110
  • Репутация: +1/-0
  • YearsYearsYearsYearsYearsYearsYearsYearsYearsYearsYearsYearsYearsYearsYears
Re: Сложный SELECT
« Ответ #16 : Декабрь 14, 2012, 05:03:47 pm »
Вообще, для понимания хотелось бы представить первую выборку в виде двух запросов, которые дадут такой же результат.

Оффлайн A.

  • Newbie
  • *
  • Сообщений: 110
  • Репутация: +1/-0
  • YearsYearsYearsYearsYearsYearsYearsYearsYearsYearsYearsYearsYearsYearsYears
Re: Сложный SELECT
« Ответ #17 : Декабрь 14, 2012, 09:30:44 pm »
Дополнительная информация: в Таблица 2 содержится 190.434 записей. На скриншоте же видно, что выбирается 172.040 записей. Согласно чему идет ограничение?
Далее - в Таблица 1 по условию в where содержится 78.542 записей, именно столько же и выбирается второй выборкой. Первой же выборкой получается 78.950 записей - плюс 408 записей.

Оффлайн A.

  • Newbie
  • *
  • Сообщений: 110
  • Репутация: +1/-0
  • YearsYearsYearsYearsYearsYearsYearsYearsYearsYearsYearsYearsYearsYearsYears
Re: Сложный SELECT
« Ответ #18 : Декабрь 14, 2012, 10:42:53 pm »
Поле keyz1_k Таблицы 2 не ключевое. Кажется, дело в том, что из первой таблицы "плывут" дубликаты, т.к. полей keyz1_k - не ключевое, и записей с одним и тем же значением может быть несколько, к которым "пристыковываются" записи из таблицы слева от LEFT. Т.к. внутренняя таблица, куда укладываются данные, объявлена как сортированная с НЕ уникальным ключом, то фокус проходит.

В общем, в первой выборке надо DISTINCT использовать, тогда количество выбираемых записей совпадает со второй выборкой.

:)

Оффлайн Удав

  • Newbie
  • *
  • Сообщений: 44
  • Репутация: +7/-0
  • YearsYearsYearsYearsYearsYearsYearsYearsYearsYearsYearsYearsYearsYearsYearsYears
Re: Сложный SELECT
« Ответ #19 : Декабрь 15, 2012, 11:59:10 pm »
You are not allowed to view links. Register or Login
В общем, в первой выборке надо DISTINCT использовать, тогда количество выбираемых записей совпадает со второй выборкой.

:)
Тихо сам с собою...
В чем был смысл поста "подскажите, пожалуйста, по такому вопросу."?
Помочь разобраться, почему left join возвращает больше записей, чем отдельный select?
Это просто: если в таблице 2 поле keyz1_k содержит неуникальные значения, то в результирующей таблице будут записи с одинаковыми полями из таблицы 1.

Но вот специально делать секрет о именах таблиц как то не способствует разбирательству.  :-\

Оффлайн Uukrul

  • SAP ECC 6.0 Ehp(*)
  • Administrator
  • Epic Member
  • *****
  • Сообщений: 3 809
  • Репутация: +47/-0
  • Пол: Мужской
  • YearsYearsYearsYearsYearsYearsYearsYearsYearsYearsYearsYearsYearsYearsYearsYearsYears
    • Sapforum.BIZ
Re: Сложный SELECT
« Ответ #20 : Декабрь 16, 2012, 01:42:24 am »
You are not allowed to view links. Register or Login
Но вот специально делать секрет о именах таблиц как то не способствует разбирательству.  :-\
Да и не ясно что в этих именах таблиц такого секретного...

Оффлайн A.

  • Newbie
  • *
  • Сообщений: 110
  • Репутация: +1/-0
  • YearsYearsYearsYearsYearsYearsYearsYearsYearsYearsYearsYearsYearsYearsYears
Re: Сложный SELECT
« Ответ #21 : Декабрь 16, 2012, 05:55:30 am »
You are not allowed to view links. Register or Login
если в таблице 2 поле keyz1_k содержит неуникальные значения, то в результирующей таблице будут записи с одинаковыми полями из таблицы 1.
Простите как бэ, я как бэ ужэ разобрался, я всегда так делаю.
Спосибо за помосчь.

Оффлайн A.

  • Newbie
  • *
  • Сообщений: 110
  • Репутация: +1/-0
  • YearsYearsYearsYearsYearsYearsYearsYearsYearsYearsYearsYearsYearsYearsYears
Re: Сложный SELECT
« Ответ #22 : Декабрь 16, 2012, 05:57:07 am »
You are not allowed to view links. Register or Login
Да и не ясно что в этих именах таблиц такого секретного...
Не вижу причин, по которым имена таблиц дали бы больше ясности. В данном случае там Z.

Оффлайн Uukrul

  • SAP ECC 6.0 Ehp(*)
  • Administrator
  • Epic Member
  • *****
  • Сообщений: 3 809
  • Репутация: +47/-0
  • Пол: Мужской
  • YearsYearsYearsYearsYearsYearsYearsYearsYearsYearsYearsYearsYearsYearsYearsYearsYears
    • Sapforum.BIZ
Re: Сложный SELECT
« Ответ #23 : Декабрь 16, 2012, 11:11:16 am »
You are not allowed to view links. Register or Login
Простите как бэ, я как бэ ужэ разобрался, я всегда так делаю.
Да нормально... зато другим будет пример...

Оффлайн Uukrul

  • SAP ECC 6.0 Ehp(*)
  • Administrator
  • Epic Member
  • *****
  • Сообщений: 3 809
  • Репутация: +47/-0
  • Пол: Мужской
  • YearsYearsYearsYearsYearsYearsYearsYearsYearsYearsYearsYearsYearsYearsYearsYearsYears
    • Sapforum.BIZ
Re: Сложный SELECT
« Ответ #24 : Декабрь 17, 2012, 10:37:53 am »
В общем подсказали тут как эта кухня работает:

Цитировать
You are not allowed to view links. Register or Login)

LEFT OUTER JOINОператор левого внешнего соединения LEFT OUTER JOIN соединяет две таблицы. Порядок таблиц для оператора важен, поскольку оператор не является симметричным.

Заголовок таблицы-результата является объединением (конкатенацией) заголовков соединяемых таблиц.

Тело результата логически формируется следующим образом. Пусть выполняется соединение левой и правой таблиц по предикату (условию) p.

1.В результат включается внутреннее соединение (INNER JOIN) левой и правой таблиц по предикату p.
2.Затем в результат добавляются те записи левой таблицы, которые не вошли во внутреннее соединение на шаге 1. Для таких записей поля, соответствующие правой таблице, заполняются значениями NULL.
так что думаю, теперь как бы понятно, почему количество записей не совпадает.

Sapforum.Biz

Re: Сложный SELECT
« Ответ #24 : Декабрь 17, 2012, 10:37:53 am »