Вопрос по oracle, sql – два левых внешних соединения не работают Oracle sql

0

В запросе четыре таблицы
Таблица содержитa_id    , имя
Таблица a_tl содержитa_tl_id , a_id, language_id, a_disp_name
Таблица б содержитb_id    , a_id, b_name
Таблица b_tl содержитb_tl_id , b_id, language_id, b_disp_name

Я хочу сделать левое внешнее соединение для a и a_tl, левое соединение для b и b_tl
и внутреннее соединение в результирующих таблицах. Я написал следующий запрос

SELECT    case  a.a_disp_name
                WHEN   null  THEN  a.a_name
                else         a.a_disp_name
          end   AS           a_name             ,
          case  b.b_disp_name
                WHEN   null  THEN  b.b_name
                else         b.b_disp_name
          end   AS           b_name             ,
          a_id                                  ,
          b_id                                  
FROM      a                                     ,
          a_tl                                  ,
          b                                     ,
          b_tl                 
WHERE     a.a_id = a_tl.a_id (+)
AND       b.b_id = b_tl.b_id (+)
AND       a_tl.language_id = 2    
AND       b_tl.language_id = 2     
AND       a.a_id= b.b_id

Этот запрос работает, если language_id присутствует в базе данных, если для определенного значения он отсутствует, он не будет работать, т.е. левое внешнее соединение не работает.

Ваш Ответ

2   ответа
3

Похоже, проблема в том, что вы не используете(+) для тебяlanguage_id чеки.
Ваш стол соединен снаружи, поэтомуlanguage_id являетсяNULL когда запись не найдена, но затем вы проверяетеlanguage_id = 2, но ?language_id являетсяNULL.

Я также не вижу, откуда вы используете результатыa_tl или жеb_tlУгадайте, это проблема вашего поста, а не вашего исходного запроса?


Однако, пожалуйста, используйте явные объединения вместо старого синтаксиса. Как только вы привыкнете к нему, его будет намного легче читать и понимать.
Ваш запрос может также выиграть от использованияCOALESCE (или жеNVL если хочешь):

SELECT COALESCE( a_tl.a_disp_name, a.a_name ) AS a_name,
       COALESCE( b_tl.b_disp_name, b.b_name ) AS b_name,
       a.a_id,
       b.b_id
FROM a
JOIN b ON ( b.b_id = a.a_id )
LEFT JOIN a_tl ON ( a_tl.a_id = a.a_id AND a_tl.language_id = 2 )
LEFT JOIN b_tl ON ( b_tl.b_id = b.b_id AND b_tl.language_id = 2 )

Надеюсь, я правильно понял ваш вопрос, спросите, если он не работает.

Спасибо за ответ. Puneet Garg
ЗдесьJOINS documentation, Не уверен, что вы подразумеваете подmultiple joins, Вы имеете в виду два условия? Все условия, необходимые для успешного внешнего соединения, помещаются туда. Вы имеете в виду мои дваLEFT JOINs? Вы можете объединить столько таблиц, сколько вам нужно.
Можете ли вы указать мне на документацию, где я могу узнать о синтаксисе множественных объединений. Я не могу понять, почему вы использовали a_tl и b_tl, а не a, bLEFT JOIN a_tl ON ( a_tl.a_id = a.a_id AND a_tl.language_id = 2 ) LEFT JOIN b_tl ON ( b_tl.b_id = b.b_id AND b_tl.language_id = 2 ) Puneet Garg
да, запрос работает. Puneet Garg
В запросе, который вы написали. Я немного запутался в порядке, в котором будут выполняться объединения, потому что нет круглых скобок. Как будто сначала будет выполнено последнее соединение, а затем то, что поверх него? Puneet Garg
1

Если ты хочешьa_tl.language_id = 2 Вы вызываете внутреннее соединение (a_tl.language_id никогда не будет нулевым).

Если вы хотите соединиться слева только со строками из a_tl с a_tl.language_id = 2, напишите так:

FROM      a 
          join b on (a.a_id= b.b_id)
          left join a_tl on ( a.a_id = a_tl.a_id and a_tl.language_id = 2)
          left join b_tl on ( b.b_id = b_tl.b_id and b_tl.language_id = 2 )
Спасибо за ответ. Puneet Garg

Похожие вопросы