I'm currently writing an SQL query for a massive finance report out of Oracle. This information isn't necessary for the question but may provide some background: I'm essentially taking all gl_JEs from a specific timeframe and breaking these up into their actual transactions.
So I have 6 different subtables i've generated and a base table.
The base table contains two keys to generate a PK and some general information Header_ID and Line_Num
Each subtable record also contains these two keys and additional information. There can be a one to many relationship between the base table and a subtable. And a PK from the base can be in multiple subtables.
I want to join these 6 table together, preserving the general information from the base and adding the information from the subtables. I can do this with a Union ALL but it means I have to put the same fields on every subtable and I have to join LOTS of fields, so this is not optimal.
Here some example data if all that talking about did not make sense. I'm going to simplify it by only having 3 sub tables:
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');
I want to return something like this. Ignore my lack of nulls/field names please
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
Any ideas?
EDIT: HEre is my actual Query as it stands now:
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