Применение OUTER JOIN в Oracle - PullRequest
       14

Применение OUTER JOIN в Oracle

0 голосов
/ 07 марта 2019

После создания 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 ]

2 голосов
/ 08 марта 2019
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 голос
/ 07 марта 2019

Это действительно двойной выход, в котором вы нуждаетесь, и в оборудовании, и в истории времени отсутствуют записи об оборудовании "e2".

Но это должно сработать. (обратите внимание на специальный синтаксис внешнего оракула)

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.

...