2016-04-05 21 views
2

Bir alt sorgu ile sınırlı bir tabloya bir dış birleştirmeye ihtiyacım var. Ancak, Oracle Dış Alt-Sorgu ile Katıl (Oracle 11g)

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

dönüyor Sonra dış başka alt sorguda blrleslr ama orijinal alt sorgu bunun için katıldı ediliyor ana tablodan bir alanda bağlıdır olarak, bu

ile başarısız iterek denedi
ORA-00904: "DTL"."TRANS_DATETIME": invalid identifier 

Bu birliğin nasıl çözümlenebileceğini öneren herhangi biri var mı?

Sorgu: I (bu konuya aslında alakasız ve tek tablo olarak düşünülebilir) işlem numarasına katılmak header ve detail tablolar

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 

açıklanması. O zamanprodcost tablosuna katılmaya ihtiyacım var. Ancak, ben Yani detail tablo ürün kimlikleri (product_code) ve işlem tarihi (trans_datetime) ile yaptığı işlemler kaydıdır En son last_amend_date önce

trans_datetime için dayalı bu kısıtlamak gerekir. prodcost tablosunda ürün kimlikleri (product_code) ve etkin bir tarih (last_amend_date) ile ürün maliyetlerinin bir kaydı vardır. Dolayısıyla, tek bir ürün, işlemin gerçekleştiği zamana bağlı olarak birden fazla maliyete sahip olabilir. Doğru maliyeti tanımlamak için product_code ve en son last_amend_date numaralı bağlantıyı trans_datetime'dan önce bağlamalıyım.

Tam sonuç kümesini sağlamak için bunları iki sorguya ve UNION'a bölebileceğimin farkındayım. Ancak, eğer mümkün olursa, bundan kaçınmayı tercih ederim. Nasıl çözüleceğine dair başka öneriler de takdir edilecektir.

+0

"ptd" ne başvuruyor? – wvdz

+1

Bazı örnek verileri ve beklenen çıktınızı paylaşırsanız, gereksinimi anlamak daha kolay olurdu. – Utsav

+0

Bu hatanın nedeni açık: "dtl.trans_datetime", tablo ayrıntılarında bir sütun değil. Bir yazım hatası belki? – wvdz

cevap

1

Aşağıda, nelerin peşinde olduğunuza ulaşmanıza yardımcı olması gereken birkaç örnek var (örnek veriler vermeyi reddettiğinizden beri kendi tablolarım/verilerimi oluşturdum, ancak ilke aynı kalıyor ve uygulamanız gerekir) o) kendi sorguları:

Örnek 1 (katılmak sol kullanarak ve analitik fonksiyonların):

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  

Örnek 2 (bir sayıl alt sorgu kullanarak):

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  

N.B. T1.id'in benzersiz olduğunu varsayalım.

+1

Örnek 1 iyi çalışıyor, teşekkürler. – Michael