在Oracle中应用OUTER JOIN

时间:2019-03-07 08:33:16

标签: oracle outer-join

创建3个表后,equip_type,output_history和time_history。 对于每行output_history,此代码将显示time_history中的最新数据。 结果看起来像这样。

 EQUIP MODEL DATE1  QUANTITY   DATE2   TIME  EQUIP_TYPE
 ---- ---- ---------- ------  -------- ----  ----------
  e1    m1  20180103  10      20180101   6    A
  e1    m1  20180106  20      20180105   5    A

但是我该如何修改代码以显示没有equip_type的行,像这样。

EQUIP MODEL DATE1  QUANTITY   DATE2   TIME  EQUIP_TYPE
 ---- ---- ---------- ------  -------- ----  ----------
  e1    m1  20180103  10      20180101   6    A
  e1    m1  20180106  20      20180105   5    A
  e2    m1  20180106  20      20180105   5   (null)
  e3    m1  20180106  20      (null)  (null) (null) 

代码如下;

 CREATE TABLE equip_type  (  
      EQUIP_TYPE VARCHAR(15),    
      EQUIP VARCHAR(15)
      );
    INSERT INTO equip_type  VALUES ('A','e1');
    CREATE TABLE output_history (  
      EQUIP VARCHAR(15),     
      MODEL VARCHAR(15),     
      Data1 VARCHAR(15),        
      QUANTITY  NUMBER(10) 
      );
    INSERT INTO output_history VALUES ('e1','m1','20180103',10);
    INSERT INTO output_history VALUES ('e1','m1','20180106',20);
    INSERT INTO output_history VALUES ('e2','m1','20180106',20);
    INSERT INTO output_history VALUES ('e3','m1','20180106',20);
    CREATE TABLE time_history (  
      EQUIP VARCHAR(15),     
      MODEL VARCHAR(15),       
      Data2 VARCHAR(15),    
      time NUMBER(10)
      );
    INSERT INTO time_history VALUES ('e1','m1','20180101',6);
    INSERT INTO time_history VALUES ('e1','m1','20180105',5);
    INSERT INTO time_history VALUES ('e2','m1','20180106',5); --added

SELECT
    o.equip,
    o.model,
    o.data1,
    o.quantity,
    t.data2,
    t.time,
    e.equip_type
FROM 
    output_history o
    INNER JOIN equip_type e ON e.equip = o.equip    --I have tried RIGHT OUTER JOIN here, but didn' work
    INNER JOIN time_history t ON t.equip = o.equip AND t.data2 <= o.data1
    AND t.data2 >= '20180101' 
WHERE NOT EXISTS (
    SELECT 1 
    FROM time_history
    WHERE 
        equip = o.equip
        AND data2 <= o.data1
        AND data2 > t.data2
        AND data2 >= '20180101' AND data2 <= '2080106' 
)AND o.data1 >= '20180101' AND o.data1 <= '20180106';

2 个答案:

答案 0 :(得分:2)

SELECT
    o.equip,
    o.model,
    o.data1,
    o.quantity,
    t.data2,
    t.time,
    e.equip_type
FROM 
    output_history o
    LEFT JOIN equip_type e ON e.equip = o.equip    
    LEFT JOIN time_history t ON t.equip = o.equip AND t.data2 <= o.data1
    AND t.data2 >= '20180101' 
WHERE NOT EXISTS (
    SELECT 1 
    FROM time_history
    WHERE 
        equip = o.equip
        AND data2 <= o.data1
        AND data2 > t.data2
        AND data2 >= '20180101' AND data2 <= '2080106' 
)AND o.data1 >= '20180101' AND o.data1 <= '20180106' ORDER BY equip, quantity;

答案 1 :(得分:1)

实际上这是您需要的双出站,设备和time_history均缺少装备的“ e2”记录。

但这应该可行。 (请注意特殊的oracle外连接语法)

SELECT
    o.equip,
    o.model,
    o.data1,
    o.quantity,
    t.data2,
    t.time,
    e.equip_type
FROM 
    output_history o, equip_type e, time_history t 
WHERE 
    o.equip = e.equip (+)
    AND o.equip = t.equip
    AND o.model = t.model
    AND t.data2 = (select max(data2) from time_history where equip = o.equip and model = o.model and data2 < o.data1)
UNION        
SELECT
    o.equip,
    o.model,
    o.data1,
    o.quantity,
    null,
    null,
    e.equip_type
FROM 
    output_history o, equip_type e
WHERE 
    o.equip = e.equip (+)
    AND NOT exists (select 1 from time_history where equip = o.equip and model = o.model)
; 

也请注意

AND t.data2 = (select max(data2) from time_history where equip = o.equip and model = o.model and data2 < o.data1)

当您要加入最新但以前的记录时,这是一种通用方法。但是在外部联接中是不可能的。这就是为什么需要UNION之后的部分。