2016-04-05 159 views
2

我需要一個外連接到由一個子查詢限制的表。但是,Oracle將返回外連接與子查詢(的Oracle 11g)

ORA-01799: a column may not be outer-joined to a sub-query 

我又試圖推動內的另一個子查詢的外連接,但作爲原始子查詢依賴於一個領域,從它被加入到主表,這將失敗,並

ORA-00904: "DTL"."TRANS_DATETIME": invalid identifier 

任何人都可以提出如何加盟能解決嗎?

查詢:

SELECT * 
FROM header hdr 
JOIN detail dtl 
    ON hdr.trans_number = ptd.trans_number 
LEFT JOIN (SELECT product_code 
        ,cost_price 
      FROM prodcost pr 
      WHERE pr.last_amend_date = (SELECT MAX(pc.last_amend_date) 
             FROM prodcost pc 
             WHERE pc.product_code = pr.product_code 
              AND pc.last_amend_date <= trunc(dtl.trans_datetime))) p 
    ON ptd.product_code = p.product_code 

說明 我有headerdetail表是參加在交易數量(這其實是無關的問題,可以考慮單個表)。然後我需要在product_code左側加入prodcost表。不過,我有一個基於最新的last_amend_date之前trans_datetime

所以detail表是產品ID(product_code)和交易日期(trans_datetime)交易的記錄來限制這一點。該prodcost表與產品ID(product_code)和有效日期(last_amend_date)產品成本的記錄。因此,根據交易發生的時間,單個產品可能有多個成本。要確定正確的成本,我需要鏈接product_code和之前的最新last_amend_date

我知道我可以分裂成兩個查詢和UNION他們這提供完整的結果集。但是,如果可能的話,我寧願避免這種情況。任何其他建議如何解決將不勝感激。

+0

什麼是'ptd'指的是? – wvdz

+1

如果您可以共享一些樣本數據和您的預期輸出,那麼理解該要求會更容易。 – Utsav

+0

該錯誤的原因很明顯:'dtl.trans_datetime'不是表格細節的列。也許是一個錯字? – wvdz

回答

1

這裏有幾個例子是應該可以幫助你實現你以後(我做了我自己的表/因爲你的數據拒絕提供樣本數據,但原理是一樣的,你應該能夠應用它自己的查詢):

例1(使用LEFT JOIN和分析功能):

with t1 as (select 1 id, to_date('01/01/2016', 'dd/mm/yyyy') dt, 'a' val from dual union all 
      select 2 id, to_date('02/03/2016', 'dd/mm/yyyy') dt, 'b' val from dual union all 
      select 3 id, to_date('03/02/2016', 'dd/mm/yyyy') dt, 'c' val from dual union all 
      select 4 id, to_date('04/01/2016', 'dd/mm/yyyy') dt, 'd' val from dual), 
    t2 as (select 1 id, 100 val, to_date('01/12/2015', 'dd/mm/yyyy') dt from dual union all 
      select 1 id, 120 val, to_date('12/12/2015', 'dd/mm/yyyy') dt from dual union all 
      select 1 id, 130 val, to_date('04/01/2016', 'dd/mm/yyyy') dt from dual union all 
      select 2 id, 200 val, to_date('01/03/2016', 'dd/mm/yyyy') dt from dual union all 
      select 3 id, 300 val, to_date('04/03/2016', 'dd/mm/yyyy') dt from dual union all 
      select 3 id, 330 val, to_date('06/03/2016', 'dd/mm/yyyy') dt from dual) 
-- end of mimicking two tables, t1 and t2, containing data. See SQL below: 
select id, 
     t1_dt, 
     t1_val, 
     t2_val 
from (select t1.id, 
       t1.dt t1_dt, 
       t1.val t1_val, 
       t2.val t2_val, 
       t2.dt t2_dt, 
       row_number() over (partition by t1.id order by t2.dt desc) rn 
     from t1 
       left outer join (select id, 
             val, 
             dt 
           from t2) t2 on (t1.id = t2.id and t2.dt <= t1.dt)) 
where rn = 1; 

     ID T1_DT  T1_VAL  T2_VAL 
---------- ---------- ------ ---------- 
     1 01/01/2016 a    120 
     2 02/03/2016 b    200 
     3 03/02/2016 c     
     4 04/01/2016 d  

例2(使用標量子查詢):

with t1 as (select 1 id, to_date('01/01/2016', 'dd/mm/yyyy') dt, 'a' val from dual union all 
      select 2 id, to_date('02/03/2016', 'dd/mm/yyyy') dt, 'b' val from dual union all 
      select 3 id, to_date('03/02/2016', 'dd/mm/yyyy') dt, 'c' val from dual union all 
      select 4 id, to_date('04/01/2016', 'dd/mm/yyyy') dt, 'd' val from dual), 
    t2 as (select 1 id, 100 val, to_date('01/12/2015', 'dd/mm/yyyy') dt from dual union all 
      select 1 id, 120 val, to_date('12/12/2015', 'dd/mm/yyyy') dt from dual union all 
      select 1 id, 130 val, to_date('04/01/2016', 'dd/mm/yyyy') dt from dual union all 
      select 2 id, 200 val, to_date('01/03/2016', 'dd/mm/yyyy') dt from dual union all 
      select 3 id, 300 val, to_date('04/03/2016', 'dd/mm/yyyy') dt from dual union all 
      select 3 id, 330 val, to_date('06/03/2016', 'dd/mm/yyyy') dt from dual) 
-- end of mimicking two tables, t1 and t2, containing data. See SQL below: 
select id, 
     dt t1_dt, 
     val t1_val, 
     (select max(val) keep (dense_rank first order by t2.dt desc) max_val 
     from t2 
     where t1.id = t2.id 
     and t2.dt <= t1.dt) t2_val 
from t1; 

     ID T1_DT  T1_VAL  T2_VAL 
---------- ---------- ------ ---------- 
     1 01/01/2016 a    120 
     2 02/03/2016 b    200 
     3 03/02/2016 c     
     4 04/01/2016 d  

注:我假設t1.id是唯一的。

+1

示例1運行良好,謝謝。 – Michael