代码之家  ›  专栏  ›  技术社区  ›  gene b.

如何重写此查询以删除Postgres中带有左/右内/外联接关键字的Oracle(+)?

  •  0
  • gene b.  · 技术社区  · 4 年前

    我在Oracle中有以下原始查询,

    select ...
    FROM nvision_trainees_t nv, plans_t p, lookup_t idp_look
    WHERE     nv.ned_id = p.trainee_ned_id(+)
          AND p.idp_type_id = idp_look.id(+)
          AND (   
                  (p.id IS NULL AND nv.organizationalstat IN ('EMPLOYEE', 'FELLOW')) 
                  OR 
                   p.id IS NOT NULL
              );
    

    此查询已迁移到Postgres,其中 (+) 不起作用。我不得不相应地重写它。因为它是在平等的右边,它意味着 RIGHT OUTER JOIN .所以我重写了下面的查询,但它是错误的。我认为原因是,最后一个条件成为了 右外接 而最初它是内部连接的一部分。 它不会给出相同的结果。

    select ...
    from nvision_trainees_t nv 
    right outer join plans_t p on p.trainee_ned_id = nv.ned_id 
    right outer join lookup_t idp_look on 
                idp_look.id = p.idp_type_id 
                /* I feel that this is wrong somehow, it became part of the RIGHT OUTER JOIN condition */
                and ((p.id is null and nv.organizationalstat in ('EMPLOYEE', 'FELLOW'))
                    or p.id is not null);
    

    关于如何使用左/右内/外联接正确重写原始查询,有什么建议吗?

    使现代化 我试过之后 JasonTrue's suggestion 将最下面的从句分离为自己的从句,它与 起初的 LEFT JOIN ,而不是重新编写的 RIGHT JOIN ,出于某种原因。换句话说,这起作用了,有人知道为什么吗?我是不是走错方向了 右外接 右手 (+) ?

      from nvision_trainees_t nv   
      left outer join plans_t p on p.trainee_ned_id = nv.ned_id 
      left outer join lookup_t idp_look on idp_look.id = p.idp_type_id 
      where((p.id is null and nv.organizationalstat in ('EMPLOYEE', 'FELLOW'))
                or p.id is not null);
    
    1 回复  |  直到 4 年前
        1
  •  2
  •   gene b.    4 年前

    (由OP添加:右侧) (+) 的确是一个 LEFT JOIN ,因此不应将其更改为 RIGHT JOIN .相反,问题如下)

    在Oracle示例中,您的最后一个“AND”子句与JOIN操作无关。在你的Postgres-one中,你把final和子句作为加入条件的一部分。

    我想你只想把final子句作为查询过滤器的一部分,而不是连接条件的一部分。下面是一个例子:

    select ...
    from nvision_trainees_t nv 
    LEFT outer join plans_t p on p.trainee_ned_id = nv.ned_id 
    LEFT outer join lookup_t idp_look on 
                idp_look.id = p.idp_type_id 
    WHERE      ((p.id is null and nv.organizationalstat in ('EMPLOYEE', 'FELLOW'))
                    or p.id is not null);
    

    我还没有对此进行测试,但在ANSI SQL中,WHERE子句通常位于连接之后,所以我 认为 这相当于您最初的查询。