2016-08-26 2 views
0

현재 Oracle에서 방대한 재무 보고서에 대한 SQL 쿼리를 작성하고 있습니다. 이 정보는 질문에는 필요하지 않지만 배경 지식을 제공 할 수 있습니다. 본질적으로 특정 기간의 모든 gl_JE를 가져 와서 실제 트랜잭션으로 분할합니다.동일한 키를 사용하여 여러 개의 테이블을 하나의 기본 테이블에 결합하십시오.

그래서 6 개의 서브 테이블과 기본 테이블을 생성했습니다.

기본 테이블은 PK 및 일부 일반 정보 HEADER_ID 및 LINE_NUM

각 서브 레코드 이러한 두 키와 부가 정보를 포함를 생성하는 두 개의 키를 포함한다. 기본 테이블과 서브 테이블 간에는 일대일 관계가있을 수 있습니다. 그리고 기반의 PK가 여러 서브 테이블에있을 수 있습니다.

하위 테이블의 정보를 추가하고 기본 정보를 그대로 유지하면서이 6 개의 테이블을 함께 결합하고자합니다. 유니온 ALL로이 작업을 수행 할 수 있지만 모든 서브 테이블에 동일한 필드를 넣어야한다는 것을 의미하므로이 필드가 최적이 아닙니다.

여기서 말하는 모든 것이 의미가없는 경우의 데이터 예입니다. 서브 테이블을 3 개만 가지고 간단하게 할 것입니다 :

create table base (Header_id int, 
       line_num int, 
       period_num int); 
create table subtable1 (header_id int, 
         line_num int, 
         cost int, 
         description varchar(50)); 
create table subtable2 (header_id int, 
         line_num int, 
         invoice_num int, 
         description varchar(50)); 
create table subtable3 (header_id int, 
         line_num int, 
         value int, 
         description varchar(50)); 

Insert into base values 
    (1, 1 , 4), 
    (1,2,4), 
    (2,5,4), 
    (2,4,4), 
    (3,1,4), 
    (4,2,5); 

Insert into subtable1 values 
    (1, 1, 50, 'Boat'), 
    (1, 1, 30, 'lifejacket'), 
    (2, 4, 4000, 'lifeinsurance'); 
Insert into subtable2 values 
    (1, 1, 89756, 'Boat supplies') 
    (2,5, 5464, 'fake invoice'); 
Insert into subtable3 values 
    (1, 2, 100, 'im running out') 
    (3, 1, 25, 'of ideas'); 

나는 이것을 반환하고 싶습니다. nulls/field 이름을 제발 무시하십시오.

1. 1,1,4,50,'BOAT' 
2. 1,1,4,30,'lifejacket' 
3. 1,1,4,89756, 'boat supplies' 
4. 1,2,4,100,'im running out' 
5. 2,5,4,5464,'fake invoice' 
6. 2,4,4,4000,'lifeinsurance' 
7. 3,1,4,25,'of ideas' 
8. 4,2,5 

아이디어가 있으십니까?

편집 :

With 
base as 
    (
     SELECT 
      gjH.PERIOD_NAME Period 
      ,gcc.SEGMENT1 || '-' || gcc.SEGMENT2 || '-' || gcc.SEGMENT3 || '-' || gcc.SEGMENT4 || '-' || gcc.SEGMENT5 || '-' || gcc.SEGMENT6 GL_COA 
      ,gjL.JE_HEADER_ID 
      ,gjL.JE_LINE_NUM 
      ,gp.period_num 
      ,gp.period_year 
      ,gjh.date_created 
      ,gjh.default_effective_date 
      ,gjh.currency_code base_currency_code 
      ,gjh.currency_code transaction_currency_code 

     FROM 
      apps.GL_JE_Batches   gjB 
      ,apps.GL_JE_HEADERS   gjH 
      ,apps.GL_JE_LINES   gjL 
      ,apps.gl_code_combinations gcc 
      ,apps.gl_periods   gp 

     WHERE 
       gjB.je_batch_id = gjH.JE_BATCH_ID 
      and gjH.JE_HEADER_ID = gjL.JE_HEADER_ID 
      and gjH.PERIOD_NAME in (:period, :period2, :period3) 
      AND gjl.CODE_COMBINATION_ID = gcc.CODE_COMBINATION_ID 
      and (gjL.accounted_dr != 0 OR gjL.accounted_cr != 0) 
      and gjH.Period_Name = gp.Period_Name 
    ) 
,Subledger as -- Not all Base records have a Subledger record! 58825 
    (-- Return all the primary keys for the Subledger and then the FK to the different distribution tables, 
     SELECT 
      base.period Period 
      ,base.GL_COA GL_COA 
      ,base.JE_Header_ID 
      ,base.JE_Line_NUM 
      ,base.period_num 
      ,base.period_year 
      ,base.date_created 
      ,base.default_effective_date 
      ,base.base_currency_code 
      ,base.transaction_currency_code 
      ,xal.GL_SL_LINK_TABLE 
      ,xal.GL_SL_LINK_ID 
      ,xal.ae_line_num 
      ,xah.ae_header_id 
      ,xah.application_id 
      ,xe.event_id 
      ,xte.entity_id 
      ,xdl.SOURCE_DISTRIBUTION_TYPE  --Tells you what table to pull lines/info from 
      ,xdl.SOURCE_DISTRIBUTION_ID_NUM_1 --Is the FK ID to the above distribution table. 
      ,decode(nvl(xdl.unrounded_accounted_dr,0),0,xdl.unrounded_accounted_cr,-1*xdl.unrounded_accounted_dr) base_amount 
      ,decode(nvl(xdl.unrounded_accounted_dr,0),0,xdl.unrounded_accounted_cr,-1*xdl.unrounded_accounted_dr) transaction_amount 

     FROM 
      base 
      ,apps.gl_import_references    gRef 
      ,xla.xla_ae_lines      xal 
      ,xla.xla_ae_headers     xah 
      ,xla.xla_events      xe 
      ,xla.xla_transaction_entities   xte 
      ,xla.xla_distribution_links   xdl 
     WHERE 

       base.JE_HEADER_ID  = gRef.JE_HEADER_ID 
      AND base.JE_LINE_NUM   = gRef.JE_LINE_NUM 
      AND gRef.GL_SL_LINK_TABLE = xal.GL_SL_LINK_TABLE 
      AND gRef.GL_SL_LINK_ID  = xal.GL_SL_LINK_ID 
      and xal.AE_HEADER_ID  = xah.ae_header_id 
      and xal.APPLICATION_ID  = xah.APPLICATION_ID 
      and xah.AE_HEADER_ID = xdl.AE_HEADER_ID 
      and xal.AE_LINE_NUM = xdl.AE_LINE_NUM 
      and xah.event_id = xe.event_id 
      and xah.application_id = xe.application_id 
      and xe.entity_id = xte.entity_id 
      and xe.APPLICATION_ID = xte.APPLICATION_ID 
    ) 

,AP_PMT_DIST as --5476 
    (
     SELECT 
     sl.period 
     ,sl.period_num 
     ,sl.period_year 
     ,sl.gl_coa 
     ,sl.JE_Header_ID 
     ,sl.JE_line_num 
     ,sl.base_amount base_amount 
     ,sl.transaction_amount transaction_amount 
     ,'AP_PMT_DIST' || '|' || apid.description description 
     ,sl.date_created 
     ,sl.default_effective_date 
     ,sl.base_currency_code 
     ,sl.Transaction_currency_code 

     FROM 
     subledger          sl 
     ,AP.AP_PAYMENT_HIST_DISTS      aphd 
     ,AP.AP_INVOICE_DISTRIBUTIONS_ALL    apid 

     WHERE 
      sl.SOURCE_DISTRIBUTION_TYPE = 'AP_PMT_DIST' 
     AND sl.SOURCE_DISTRIBUTION_ID_NUM_1 = aphd.payment_hist_dist_id 
     and apid.invoice_distribution_id = aphd.invoice_distribution_id 
    ) 
,AP_INV_DIST as --4422 
    (
     SELECT 
     sl.period 
     ,sl.period_num 
     ,sl.period_year 
     ,sl.gl_coa 
     ,sl.JE_header_id 
     ,sl.je_line_num 
     ,sl.base_amount base_amount 
     ,sl.transaction_amount transaction_amount 
     ,'AP_INV_DIST' || '|' || apid.description description 
      ,sl.date_created 
      ,sl.default_effective_date 
     ,sl.base_currency_code 
     ,sl.Transaction_currency_code 
     FROM 
     subledger       sl 
     ,AP.AP_INVOICE_DISTRIBUTIONS_ALL apid 
     WHERE 
       sl.SOURCE_DISTRIBUTION_TYPE = 'AP_INV_DIST' 
      AND sl.SOURCE_DISTRIBUTION_ID_NUM_1 = apid.INVOICE_DISTRIBUTION_ID 
    ) 
,AP_PREPAY as --10 records 
    (
     SELECT 
     sl.period 
     ,sl.period_num 
     ,sl.period_year 
     ,sl.gl_coa 
     ,sl.JE_header_id 
     ,sl.je_line_num 
     ,sl.base_amount base_amount 
     ,sl.transaction_amount transaction_amount 
     ,'AP_PREPAY' || '|' || apid.description description 
      ,sl.date_created 
      ,sl.default_effective_date 
     ,sl.base_currency_code 
     ,sl.Transaction_currency_code 

     FROM 
     subledger       sl 
     ,AP.AP_PREPAY_APP_DISTS   appad 
     ,AP.AP_Invoice_distributions_all apid 
     WHERE 
       sl.SOURCE_DISTRIBUTION_TYPE = 'AP_PREPAY' 
       AND sl.SOURCE_DISTRIBUTION_ID_NUM_1 = appad.PREPAY_APP_DIST_ID 
       AND appad.Invoice_distribution_id = apid.invoice_distribution_id 
    ) 
,AR_DIST as --34321 records 
    (
     SELECT 
     sl.period 
     ,sl.period_num 
     ,sl.period_year 
     ,sl.gl_coa 
     ,sl.JE_header_id 
     ,sl.je_line_num 
     ,sl.base_amount base_amount 
     ,sl.transaction_amount transaction_amount 
     ,'AR Invoice Line' description 
      ,sl.date_created 
      ,sl.default_effective_date 
     ,sl.base_currency_code 
     ,sl.Transaction_currency_code 
     FROM 
     subledger       sl 
     ,AR.AR_DISTRIBUTIONS_ALL   ARDA 
     WHERE 
       sl.SOURCE_DISTRIBUTION_TYPE = 'AR_DISTRIBUTIONS_ALL' 
      and sl.SOURCE_DISTRIBUTION_ID_NUM_1 = ARDA.line_id 
    ) 
,AR_CUST_TRX as --14596 records 
    (
     SELECT 
     sl.period 
     ,sl.period_num 
     ,sl.period_year 
     ,sl.gl_coa 
     ,sl.JE_header_id 
     ,sl.je_line_num 
     ,sl.base_amount base_amount 
     ,sl.transaction_amount transaction_amount    
     ,'Cust_Trx_Line' description 
      ,sl.date_created 
      ,sl.default_effective_date 
      ,sl.base_currency_code 
      ,sl.transaction_currency_code 

     FROM 
     subledger       sl 
     ,AR.RA_CUST_TRX_LINE_GL_DIST_ALL  ctld 
     ,AR.RA_Customer_trx_lines_all  ctl 
     WHERE 
       sl.SOURCE_DISTRIBUTION_TYPE = 'RA_CUST_TRX_LINE_GL_DIST_ALL' 
      AND sl.source_distribution_id_num_1 = ctld.cust_trx_line_gl_dist_id 
      AND ctld.customer_trx_line_id = ctl.customer_trx_line_id (+) 
      --and ctld.amount <> ctl.revenue_amount 
    ) 
,spreads as 
    (
     SELECT 
      b.PERIOD Period 
      ,b.period_num 
      ,b.period_year 
      ,b.GL_COA 
      ,b.JE_HEADER_ID 
      ,b.JE_LINE_NUM 
      ,decode(nvl(gjl.accounted_dr,0),0,gjl.accounted_cr,-1*gjl.accounted_dr) base_amount 
      ,decode(nvl(gjl.accounted_dr,0),0,gjl.accounted_cr,-1*gjl.accounted_dr) transaction_amount 
      ,gjH.DESCRIPTION DESCRIPTION 
      ,b.date_created 
      ,b.default_effective_date 
      ,b.base_currency_code 
      ,b.transaction_currency_code   


     FROM 
      base      B 
      ,apps.GL_JE_HEADERS   gjH 
      ,apps.GL_JE_LINES   gjL 

     WHERE 
       B.JE_Header_ID = gjH.JE_Header_ID 
      AND B.JE_Line_Num = gjL.JE_Line_num  
      and gjH.JE_HEADER_ID = gjL.JE_HEADER_ID 
      and gjH.JE_CATEGORY = 'Adjustment' 
      and gjH.JE_SOURCE = 'Spreadsheet' 
    )  
-- okay now we have all the types! and the number of records line up from the subledger distribution list. 
-- Now we need to get the required information about each transaction. 
-- We will need to pass: Base table linking information (JEHeader and JELine) and Information about the line. 
-- Then we will join these all together. 
--Okay I have a breakdown, lets first get the values and make sure it all lines up. 
    --select * from ar_cust_trx; 
    --select * from AP_INV_DIST; 


    SELECT * FROM AP_INV_DIST AID --4422 
    UNION ALL 
    Select * FROM AP_PMT_DIST APD --9898 5476 
    Union ALL 
    select * FROM AP_PREPAY  APR --9908 10 
    Union ALL 
    select * FROM AR_DIST  ARD --44229 34321 
    Union ALL 
    select * FROM AR_CUST_TRX ARC --58825 It got rid of duplicates within itself, despite the fact they arn't duplicates. 
    Union ALL 
    select * FROM spreads --60011 1186 
+1

같은 열 (마지막 것)에서 다른 테이블의 값을 가져오고 싶지만 "더 작은 테이블"에 PK 값이 없으면 null을 허용합니다. 왼쪽 외부 조인의 결과 사이에 UNION ALL 이외의 다른 것을 생각할 수 없습니다. 또는 작은 테이블을 먼저 UNION ALL로 설정 한 다음 실제 요구 사항과 일치하는 경우 하나의 큰 외부 조인을 수행하십시오. – mathguy

+0

@mathguy 내 nulls 무시할 말을했는데 ... 내가 정말로 원하는 Header_ID, Line_Num, 비용, Invoice_num, 값, 설명 일부는 null이 될 수 있습니다. – Cameron

+0

"LOTS of fields"를 임시 테이블에 구축하는 방법과 각 하위 테이블과 관련된 열만 삽입하는 것이 아니라 임시 테이블에서 선택하는 것입니다. 각 삽입 중에 temp/staging 테이블이 null을 허용하는 한 관련 열을 처리해야합니다. – Matt

답변

0

그냥 UNION ALL 사용 -이 라인을 따라 뭔가 : 지금의 약자로 여기 내 실제 쿼리는 같은

SELECT DISTINCT * FROM 
(
     SELECT 
      base.header_id 
      , base.line_num 
      , base.period_num 
      , subtable1.cost col3 
      , subtable1.description col4 
     FROM 
      base 
      left join subtable1 
      on base.header_id = subtable1.header_id and base.line_num = subtable1.line_num 

    UNION ALL 

     SELECT 
      base.header_id 
      , base.line_num 
      , base.period_num 
      , subtable2.invoice_num 
      , subtable2.description 
     FROM 
      base 
      left join subtable2 
      on base.header_id = subtable2.header_id and base.line_num = subtable2.line_num 

    UNION ALL 

     ... 
) 

난 그냥,이 자유를 썼다하지만 뭔가를 트릭을해야합니다, 나는 믿습니다.

희망이 도움이됩니다!

+0

5 열만 있으면 작동합니다. ,하지만 약 25 개를 반환해야합니다.이 중 일부는 다른 곳에서 가져오고 일부 테이블에서는 null 일 수 있습니다. 이렇게하면 쿼리에 추가 정보를 추가하거나 항목 순서를 변경하여 선택 항목을 업데이트해야하므로 큰 어려움이 있습니다. 모든 서브 테이블을 변경할 때마다 – Cameron

+0

hearya, @Cameron, 슬프게도 더 좋은 방법이 있는지 확신하지 못합니다 ... 귀하의 검색어가 동일한 문제를 야기 할 수도 있습니다.이 검색어를 사용하면 최소한 구획화 된 널 열은 해당 테이블의 반환 값에 대한 간단한', null'으로 쉽게 설명 할 수 있습니다. –

+0

다시 한 번 더 나은 솔루션을 얻을 수 있기를 바랍니다. 그러나 나는 그렇지 않을 수도 있습니다. 다른 사람들이 제안합니다 .... –