外部联接在Oracle中的应用

外部联接在Oracle中的应用,oracle,outer-join,Oracle,Outer Join,创建3个表后,配置\u类型、输出\u历史和时间\u历史。 此代码用于为每行输出历史显示时间历史中的最新数据。 结果是这样的 EQUIP MODEL DATE1 QUANTITY DATE2 TIME EQUIP_TYPE ---- ---- ---------- ------ -------- ---- ---------- e1 m1 20180103 10 20180101 6 A e1 m1 20180106 20

创建3个表后,配置\u类型、输出\u历史和时间\u历史。 此代码用于为每行输出历史显示时间历史中的最新数据。 结果是这样的

 EQUIP MODEL DATE1  QUANTITY   DATE2   TIME  EQUIP_TYPE
 ---- ---- ---------- ------  -------- ----  ----------
  e1    m1  20180103  10      20180101   6    A
  e1    m1  20180106  20      20180105   5    A
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) 
但是如何修改代码以显示没有设备类型的行,如下所示

 EQUIP MODEL DATE1  QUANTITY   DATE2   TIME  EQUIP_TYPE
 ---- ---- ---------- ------  -------- ----  ----------
  e1    m1  20180103  10      20180101   6    A
  e1    m1  20180106  20      20180105   5    A
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';

事实上,这是你需要的一个双重输出,设备和时间历史都缺少设备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)

当您想要加入到最近但以前的记录时,这是一种通用方法。但在外部联接中是不可能的。这就是为什么需要工会后的角色

您是否尝试过在内部连接设备上使用左连接?e.Equipm=o.Equipment上的e类型。时间历史记录中没有e2,因此不清楚您为什么希望日期2为20180105e2@Peter帕夫,我刚刚加了一行我写的
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;