两个左外连接不能正常工作的Oracle sql

时间:2012-06-19 07:02:50

标签: sql oracle

查询中有四个表
表a包含 a_id ,a_name
表a_tl包含 a_tl_id ,a_id,language_id,a_disp_name
表b包含 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 个答案:

答案 0 :(得分:3)

问题是,您没有使用(+)进行language_id检查 您的表是外部加入的,因此当找不到记录时language_idNULL,但是您检查language_id = 2,但是? language_idNULL

我也不知道您使用a_tlb_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 )

希望我的问题是正确的,请询问它是否无效。

答案 1 :(得分:1)

如果你想要a_tl.language_id = 2强制进行内连接(a_tl.language_id永远不会为null)。

如果你想只使用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 )