3个表之间的左外连接

时间:2012-12-19 11:54:47

标签: sql oracle join

我有3张桌子。

  1. 座位表
  2. 本地员工
  3. 外籍员工。
  4. 座位和本地之间有一个共同的列,person_id告诉哪个人坐在哪个座位上。

    在Seat和Foreign表之间的方式相同,也是person_id。

    我能够获得座位和本地...以及座位和外国人所需的数据,使用左外连接获得空座位和空座位的空座位。

    我的问题是,我是否可以使用两个表获得单个查询映射座位表并获得合并报告?

    现在使用的查询是:

    select seat.apeh05_person_id_k
          ,seat.apeh18_seat_r seatNo
          , seat.apeh17_floor_k  seatFloor
          ,vendor.apeh15_cds_d cdsid
          , vendor.apeh15_first_n firstname
          , vendor.apeh15_last_n lastname
          ,vendor.apeh15_supervisor_cds_d ll6cdsid
          ,vendor.apeh15_ll5_cds_d ll5cdsid
          , vendor.apeh15_ll4_cds_d ll4cdsid 
     from iapeh18_seat seat ,
           IAPEH15_VENDOR_EMPLOYEE  vendor
     where seat.apeh05_person_id_k = vendor.apeh15_vendor_employee_k (+) 
     order by   seat.apeh05_person_id_k asc
    

    另一个问题是:

    select seat.apeh05_person_id_k
          ,seat.apeh18_seat_r seatNo
          , seat.apeh17_floor_k  seatFloor
          ,local.apeh09_cds_d cdsid
          ,local.apeh09_first_n firstname
          , local.apeh09_last_n lastname
          ,local.apeh09_supervisor_cds_d ll6cdsid
          ,local.apeh09_ll5_cds_d ll5cdsid
          ,  local.apeh09_ll4_cds_d ll4cdsid 
     from iapeh18_seat seat 
            , IAPEH09_LOCAL_EMPLOYEE local
     where seat.apeh05_person_id_k = local.apeh05_candidate_k (+)
     order by seat.apeh05_person_id_k asc
    

3 个答案:

答案 0 :(得分:3)

可能是Remko Jansen答案的更有效版本

select seat.apeh05_person_id_k person_id
      ,seat.apeh18_seat_r seatNo
      ,seat.apeh17_floor_k  seatFloor
      ,employee.apeh15_cds_d cdsid
      ,employee.apeh15_first_n firstname
      ,employee.apeh15_last_n lastname
      ,employee.apeh15_supervisor_cds_d ll6cdsid
      ,employee.apeh15_ll5_cds_d ll5cdsid
      ,employee.apeh15_ll4_cds_d ll4cdsid 
  from iapeh18_seat seat ,
    (select * from IAPEH15_VENDOR_EMPLOYEE  
      union all
     select * from IAPEH09_LOCAL_EMPLOYEE
    ) employee
   where seat.apeh05_person_id_k = employee.apeh05_candidate_k (+)
   order by apeh05_person_id_k

首先加入并加入之后 - 省去了做不同行的麻烦(非常昂贵的操作)。

答案 1 :(得分:1)

你可以像这样,但我不确定这是不是你想要的。如果本地和供应商的个人身份都在apeh05_person_id_k中,您希望发生什么?

此外,您通常需要外键约束,现在这是不可能的,因为seat.apeh05_person_id_k可以包含来自两个表的ID。

总而言之,我认为这就是你所要求的,但我认为你的设计是有缺陷的。

select 
  seat.*, -- Omitted field list for readability
  nvl2(local.apeh05_candidate_k, local.WhateverField, vendor.WhateverField) as WhateverField,
  nvl2(local.apeh05_candidate_k, local.YetAnotherField, vendor.YetAnotherField) as YetAnotherField
from 
  iapeh18_seat seat
  LEFT JOIN IAPEH15_VENDOR_EMPLOYEE vendor
    ON seat.apeh05_person_id_k = vendor.apeh15_vendor_employee_k
  LEFT JOIN IAPEH09_LOCAL_EMPLOYEE local
    ON seat.apeh05_person_id_k = local.apeh05_candidate_k
order by   
  seat.apeh05_person_id_k asc

答案 2 :(得分:1)

由于两个查询都包含完全相同的列,因此可以将它们与UNION语句合并在一起,如下所示:

select seat.apeh05_person_id_k person_id
      ,seat.apeh18_seat_r seatNo
      ,seat.apeh17_floor_k  seatFloor
      ,vendor.apeh15_cds_d cdsid
      ,vendor.apeh15_first_n firstname
      ,vendor.apeh15_last_n lastname
      ,vendor.apeh15_supervisor_cds_d ll6cdsid
      ,vendor.apeh15_ll5_cds_d ll5cdsid
      ,vendor.apeh15_ll4_cds_d ll4cdsid 
  from iapeh18_seat seat ,
       IAPEH15_VENDOR_EMPLOYEE  vendor
 where seat.apeh05_person_id_k = vendor.apeh15_vendor_employee_k (+) 
UNION
select seat.apeh05_person_id_k person_id
      ,seat.apeh18_seat_r seatNo
      ,seat.apeh17_floor_k  seatFloor
      ,local.apeh09_cds_d cdsid
      ,local.apeh09_first_n firstname
      ,local.apeh09_last_n lastname
      ,local.apeh09_supervisor_cds_d ll6cdsid
      ,local.apeh09_ll5_cds_d ll5cdsid
      , local.apeh09_ll4_cds_d ll4cdsid 
 from iapeh18_seat seat 
        , IAPEH09_LOCAL_EMPLOYEE local
 where seat.apeh05_person_id_k = local.apeh05_candidate_k (+)
 order by person_id

UNION运算符返回任一结果中出现的所有不同行。 请参阅:The UNION [ALL], INTERSECT, MINUS Operators