Sql returning with 4-5 minutes delay [closed] - sql

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 21 days ago.
Improve this question
I'm trying to fetch the details of employee payment from Oracle Fusion HCM tables with he help of below SQL query but the results I'm getting with 4-5 minutes of delay. Need help on how can I improve the performance of this SQL query.
As I'm new to SQL and not aware of all the functionalities and best practices available in SQL. Please help as this query is from the support project what I'm working in
SELECT DISTINCT papf.person_number,
ppnf.full_name name,
bal.balance_value,
fi.instance_name,
fabu.bu_name
FROM pay_payroll_actions ppa,
pay_all_payrolls_f pay,
pay_payroll_rel_actions pra,
pay_pay_relationships_dn pprd,
per_all_people_f papf,
per_all_assignments_m paam,
per_person_names_f ppnf,
fun_all_business_units_v fabu,
pay_time_periods ptp,
pay_person_pay_methods_f ppm,
pay_action_classes pac,
pay_balance_types_vl pbt,
PAY_FLOW_INSTANCES fi,
PAY_REQUESTS pr,
TABLE(
pay_balance_view_pkg.get_balance_dimensions (
p_balance_type_id => pbt.balance_type_id,
p_payroll_rel_action_id => pra.payroll_rel_action_id,
p_payroll_term_id => NULL,
p_payroll_assignment_id => NULL
)
) bal,
pay_dimension_usages_vl pdu,
PAY_ORG_PAY_METHODS_F popf1
WHERE ppa.action_type IN ('Q', 'R')
AND ppa.effective_date BETWEEN to_date(
:p_pay_period,
'MON-YY',
'nls_date_language=American'
) AND LAST_DAY(
to_date(
:p_pay_period,
'MON-YY',
'nls_date_language=American'
)
)
AND pay.payroll_id = ppa.payroll_id
AND ppa.PAYROLL_ACTION_ID = pra.PAYROLL_ACTION_ID
AND pr.PAY_REQUEST_ID = ppa.PAY_REQUEST_ID
AND fi.FLOW_INSTANCE_ID = pr.FLOW_INSTANCE_ID
AND pay.payroll_name = NVL(:p_payroll, pay.payroll_name)
AND ppa.effective_date BETWEEN pay.effective_start_date AND pay.effective_end_date
AND pra.payroll_action_id = ppa.payroll_action_id
AND pra.retro_component_id IS NULL
AND pra.action_status = 'C'
AND pprd.payroll_relationship_id = pra.payroll_relationship_id
AND ppa.effective_date BETWEEN pprd.start_date AND pprd.end_date
AND papf.person_id = pprd.person_id
AND ppa.effective_date BETWEEN papf.effective_start_date AND papf.effective_end_date
AND paam.person_id = papf.person_id
AND paam.assignment_type = 'E'
AND paam.primary_flag = 'Y'
AND paam.effective_latest_change = 'Y'
AND ppa.effective_date BETWEEN paam.effective_start_date AND paam.effective_end_date
AND ppnf.person_id = pprd.person_id
AND ppnf.name_type = 'GLOBAL'
AND ppa.effective_date BETWEEN ppnf.effective_start_date AND ppnf.effective_end_date
AND fabu.bu_id = paam.business_unit_id
AND ppa.effective_date BETWEEN fabu.date_from AND fabu.date_to
AND (
LEAST(:company_name) IS NULL
OR (
DECODE(
:company_name,
'Company 1',
1,
0
) = 1
AND fabu.bu_name IN (
'Company 2',
'Shared Service BU'
)
)
OR (
DECODE(
:company_name,
'Company 3',
1,
0
) = 0
AND fabu.bu_name IN (:company_name)
)
)
AND pay.payroll_id = ptp.payroll_id
AND ptp.period_category IN ('E', 'C')
AND TO_CHAR(
ptp.start_date,
'MON-YY',
'NLS_DATE_LANGUAGE = american'
) IN (:p_pay_period)
AND ppm.payroll_relationship_id(+) = pprd.payroll_relationship_id
AND pac.action_type = ppa.action_type
AND pac.classification_name = 'SEQUENCED'
AND pbt.legislation_code = 'SA'
AND pbt.balance_name IN ('Net Pay')
AND pdu.database_item_suffix = '_REL_RUN'
AND pdu.balance_dimension_id = bal.balance_dimension_id
AND pdu.legislation_code = 'SA'
AND bal.balance_value <> 0
AND ppm.org_payment_method_id = popf1.org_payment_method_id(+)
AND EXISTS (
SELECT 1
FROM pay_paymt_search_results_vl ppsrv,
pay_action_interlocks pai,
pay_payroll_rel_actions pre_rel_actions,
pay_payroll_actions pre_actions
WHERE (
ppsrv.person_number = pprd.payroll_relationship_number
OR ppsrv.person_number || '-1' = pprd.payroll_relationship_number
OR ppsrv.person_number || '-2' = pprd.payroll_relationship_number
OR ppsrv.person_number || '-3' = pprd.payroll_relationship_number
)
AND pai.locked_action_id = pra.payroll_rel_action_id
AND pre_rel_actions.payroll_rel_action_id = pai.locking_action_id
AND pre_actions.payroll_action_id = pre_rel_actions.payroll_action_id
AND ppsrv.opm IN (:PAYMENT_METHOD)
AND ppsrv.payroll_rel_action_id = pre_rel_actions.payroll_rel_action_id
AND ppsrv.process_date BETWEEN ptp.start_date AND ptp.end_date
)
ORDER BY papf.person_number

DISTINCT is never fast
Lot of WHERE conditions will not use any indexes because of the usage of functions (conversion of dates, DECODE, ...)
the DECODEs could be rewrite in more efficient way
testing for NULL doesn't use an index - if any - unless part of a compound one
the usage of the TABLE() on a (pipelined?) function could be optimized because only 2 conditions are used on the result: you should better have a more suited get_balance_dimensions() version to which you pass the conditions (pdu.balance_dimension_id and balance_value <> 0), the filtering inside the function will most probably speed up the processing (more extreme solution would be to put it in a CTE with materialize hint)
LEAST on 1 argument is useless (but the optimizer should strip it) but raises the question: is really what you want to do ?
...

I don't know if your data needs to be real time but if not, I wonder if it would be prudent to create an additional table to hold the complexity of this query and update it on a schedule (nightly?). Have the new table do all the joins and math when a 5 min query doesn't hurt anything leaving this query as a simple select * from payTablesCombined.

you should use this solution
SELECT
...........
FROM pay_payroll_actions ppa
left join pay_all_payrolls_f pay on pay.payroll_id = ppa.payroll_id
.....
Should use join

Related

Select Max date column in a sql query, which is joined to other columns

I have an Oracle Query below
select papf.person_number, to_char(hrcd.SUBMITTED_DATE, 'DD-Mon-YYYY','NLS_DATE_LANGUAGE = American') as "Resignation Date", paam.last_update_date as assignmentupdate, hrcd.last_update_date as hrcdupdate, hth.last_update_date as hthupdate
from
per_all_people_f papf, per_all_assignments_m paam, hrc_txn_header hth, HRC_TXN_DATA hrcd
where
papf.person_id=paam.person_id
and paam.assignment_type IN ('E','C')
and paam.assignment_status_type in ('ACTIVE')
and paam.primary_flag = 'Y'
and paam.EFFECTIVE_LATEST_CHANGE ='Y'
and trunc(sysdate) between trunc(paam.effective_start_date) and trunc(paam.effective_end_date)
and trunc(sysdate) between trunc(papf.effective_start_date) and trunc(papf.effective_end_date)
and paam.person_id=hth.subject_id(+)
and paam.assignment_id=hth.object_id(+)
and hth.module_identifier(+) IN ('Resignation','Terminations')
and hrcd.transaction_id(+)=hth.transaction_id
and papf.person_number IN ('901626', '900723', '900846');
Which is giving below result
Now I am Person 900846 has multiple rows coming, now I need to extract the max date from this column for that I added the below logic but this is not working
select papf.person_number, to_char(hrcd.SUBMITTED_DATE, 'DD-Mon-YYYY','NLS_DATE_LANGUAGE = American') as "Resignation Date", paam.last_update_date as assignmentupdate, hrcd.last_update_date as hrcdupdate, hth.last_update_date as hthupdate
from
per_all_people_f papf, per_all_assignments_m paam, hrc_txn_header hth, HRC_TXN_DATA hrcd
where
papf.person_id=paam.person_id
and paam.assignment_type IN ('E','C')
and paam.assignment_status_type in ('ACTIVE')
and paam.primary_flag = 'Y'
and paam.EFFECTIVE_LATEST_CHANGE ='Y'
and trunc(sysdate) between trunc(paam.effective_start_date) and trunc(paam.effective_end_date)
and trunc(sysdate) between trunc(papf.effective_start_date) and trunc(papf.effective_end_date)
and paam.person_id=hth.subject_id(+)
and paam.assignment_id=hth.object_id(+)
and hth.module_identifier(+) IN ('Resignation','Terminations')
and hrcd.transaction_id(+)=hth.transaction_id
and hrcd.SUBMITTED_DATE =
(SELECT MAX(hrcd2.SUBMITTED_DATE)
FROM HRC_TXN_DATA hrcd2, hrc_txn_header hth2, per_all_assignments_m paam2
WHERE hrcd2.TRANSACTION_ID = hrcd.TRANSACTION_ID
AND hrcd2.transaction_id=hth2.transaction_id
and hth2.module_identifier IN ('Resignation','Terminations')
and paam2.assignment_id=hth2.object_id
and paam2.assignment_id=paam.assignment_id
)
and papf.person_number IN ('901626', '900723', '900846');
But now the Output is like below
I am not sure how the outer join will be added in the second query and even after after that the result should 3 lines of data each for employee with max resignation date and blank is resignation date is null
Output should look like below
can someone help me in this?
Thanks,
Shivam
You can use window functions (ROW_NUMBER | RANK | DENSE_RANK | MAX OVER) to rank your rows and only pick the latest per person. E.g.:
select person_number, "Resignation Date", assignmentupdate, hrcdupdate, hthupdate
from
(
select
papf.person_number,
to_char(hrcd.submitted_date, 'DD-Mon-YYYY', 'NLS_DATE_LANGUAGE = American') as "Resignation Date",
paam.last_update_date as assignmentupdate,
hrcd.last_update_date as hrcdupdate,
hth.last_update_date as hthupdate,
hrcd.submitted_date,
max(hrcd.submitted_date) over (partition by papf.person_number) as max_submitted_date
from per_all_people_f papf
join per_all_assignments_m paam on paam.person_id = papf.person_id
left join hrc_txn_header hth on hth.subject_id = paam.person_id
and hth.object_id = paam.assignment_id
and hth.module_identifier IN ('Resignation', 'Terminations')
left join HRC_TXN_DATA hrcd on hrcd.transaction_id = hth.transaction_id
where papf.person_number IN (901626, 900723, 900846)
and paam.assignment_type IN ('E', 'C')
and paam.assignment_status_type in ('ACTIVE')
and paam.primary_flag = 'Y'
and paam.effective_latest_change = 'Y'
and trunc(sysdate) between trunc(paam.effective_start_date) and trunc(paam.effective_end_date)
and trunc(sysdate) between trunc(papf.effective_start_date) and trunc(papf.effective_end_date)
)
where (submitted_date = max_submitted_date)
or (submitted_date is null and max_submitted_date is null)
order by person_number;

Correlated Subquery and Arithmetic in Oracle SQL

This is my second time posting, I got a lot of good feedback from the first post regarding some difficulties. I am working on improving my SQL skills and building this query but I do not understand how to approach
* i managed to correct all original errors in my question but have one last doubt *
select wo.si_number,ivh.total_cost, wo.bill_name,pnm.pn, pnm.description, woqh.approved_date,ivh.total_price,
(select sum(ivh.total_price - ivh.total_cost) / nullif(ivh.total_price,0) from invc_header ivh where wqh_auto_key = wqh.wqh_auto_key group by ivh.total_price) as CTP,
ivh.post_date, wwt.description, wqh.WQH_AUTO_KEY, wqh.POST_DESC
from wo_operation wo, parts_master pnm,wo_quote_header wqh,
wo_quote_detail wqd, invc_header ivh, wo_work_type wwt, wo_quote_header woqh
where wo.pnm_auto_key = pnm.pnm_auto_key
and wo.woo_auto_key = wqd.woo_ref
and wqd.wqh_auto_key = wqh.wqh_auto_key
and wqh.WQH_NUMBER = woqh.WQH_NUMBER
and ivh.wqh_auto_key (+)= wqh.wqh_auto_key
and wwt.wwt_auto_key (+)= wo.wwt_auto_key
and wo_type = 'External'
and wqh.POST_DESC is not NULL
and woqh.approved_date between to_date('01/01/2020', 'MM/DD/YYYY') and to_date('01/31/2020', 'MM/DD/YYYY')
order by ctp
I m not sure how to have the script only pull the rows whose ctp is < 30; how would I incorporate that?
As long as your CTP column is a number you could add that to your WHERE like show below where I added it to the end of your query's WHERE clause.
SELECT wo.si_number,
ivh.total_cost,
wo.bill_name,
pnm.pn,
pnm.description,
woqh.approved_date,
ivh.total_price,
(
SELECT SUM(ivh.total_price - ivh.total_cost) / NULLIF(ivh.total_price, 0)
FROM invc_header ivh
WHERE wqh_auto_key = wqh.wqh_auto_key
GROUP BY ivh.total_price
) AS CTP,
ivh.post_date,
wwt.description,
wqh.WQH_AUTO_KEY,
wqh.POST_DESC
FROM wo_operation wo,
parts_master pnm,
wo_quote_header wqh,
wo_quote_detail wqd,
invc_header ivh,
wo_work_type wwt,
wo_quote_header woqh
WHERE wo.pnm_auto_key = pnm.pnm_auto_key
AND wo.woo_auto_key = wqd.woo_ref
AND wqd.wqh_auto_key = wqh.wqh_auto_key
AND wqh.WQH_NUMBER = woqh.WQH_NUMBER
AND ivh.wqh_auto_key (+)= wqh.wqh_auto_key
AND wwt.wwt_auto_key (+)= wo.wwt_auto_key
AND wo_type = 'External'
AND wqh.POST_DESC IS NOT NULL
AND woqh.approved_date BETWEEN to_date('01/01/2020', 'MM/DD/YYYY') AND to_date('01/31/2020', 'MM/DD/YYYY')
AND CTP <= 30
ORDER BY ctp;
A simple less than or equal to operation will filter your results to the desired range, so you get only those less than 30 as requested. Also if you need 29 and down you can omit the =

Multiple AND conditions in case statement

I've got an Oracle table CUST with Fields YEAR and STATUS. I'm trying to write a statement that will select the records where ((CUST.YEAR = '2017' and CUST.STATUS = 'ACTIVE') and where (CUST.YEAR = '2018' and CUST.STATUS = 'ACTIVE')). When both of these statements are true, I want to return '1' else '0'
select *
from cust
where cust.year = '2017' and cust.status = 'Active'
returns the correct number of rows (394).
select *
from cust
where cust.year = '2018' and cust.status = 'Active'
returns the correct number of rows (451).
Here's where the wheels fall off (due to my inexperience with SQL scripting). I've tried to combine the two select statements and I either gets tens of thousands of rows or errors because of incorrect syntax. This is before even attempting to use a case statement to return a comparative result (if both of these conditions, then '1' else '0').
I realize this is probably pretty elementary stuff but the syntax is beyond me as of now. Would someone be kind enough to help me construct this statement?
The few times I've posted to this forum I've learned things that help to make me more self-sufficient, so I offer my thanks in advance.
You can take advantage of IN here:
select *
from cust
where cust.year IN ('2017', '2018') and
cust.status = 'Active'
The way I understood it, or might be what you're looking for, i.e.
select *
from cust
where (cust.year = '2017' and cust.status = 'Active')
or (cust.year = '2018' and cust.status = 'Active');
which - as William says - leads to
where cust.status = 'Active'
and cust.year in ('2017', '2018')
If I have understood your requirement correctly you want to determine whether your table has records for both pairs of conditions, that is , whether you have active records for both 2017 and 2018. The solutions provided so far will assert whether either condition is true but not both.
So here is a solution which satisfies your actual requirement. We have a WITH clause which selects one active record for each year (which is all your need). The inline view then counts how many records it found. If the count is two then you have active records for both years.
with tst as (
select cust.cust_id, cust.year
from cust
where cust.year = '2017'
and cust.status = 'Active'
group by cust.cust_id, cust.year
union all
select cust.cust_id, cust.year
from cust
where cust.year = '2018'
and cust.status = 'Active'
group by cust.cust_id, cust.year
)
select cust_id
, case when cnt = 2 then 1 else 0 end as your_condition
from ( select cust_id, count(*) as cnt
from tst
group by cust_id )
/

A long query tuning

I have the following query, in this query, I am selecting the ebs tables, with a custom table which has header_id and populating the the data in a custom table XXREPORT_L1_TBL.
I want to tune this query.
[update] made changes to the query as bellow:
splited the query in 3 different insert statements
removed the columns which do in line queries for values
added an update statement at the end for these columns.
insert into XX.XXREPORT_L1_TBL ( ORDER_NUMBER
, LINE_NUMBER
, UOM
, CUSTOMER_LENGTH
, THEORETICAL_WEIGHT
, FINISH
, ORDER_QTY_PCS
, ORDER_QTY_KGS
, SALES_VALUE
, TOTAL_VALUE
, ORDERED_QUANTITY
, WIP_ENTITY_ID
, JOB_NAME
, JOB_TYPE
, JOB_STATUS
, JOB_RELEASED_DATE
, DATE_COMPLETED
, DATE_CLOSED
, JOB_CARD_QTY
, ALLOY
, PROFILE
, PROD_QTY_KGS
, COST_KGS_THEORY
, COST_KGS_ACTUAL
)
SELECT
---- Sales Order
xx.order_number
,xx.line_number
,xx.UOM,
xx.customer_length,
xx.theoretical_weight,
xx.finish,
xx.order_qty_pcs,
xx.order_qty_kgs,
xx.sales_value, -- total value / total kgs
xx.total_value, -- line total
xx.ordered_quantity,
-- Production
xx.wip_entity_id,
xx.job_name,
( select case when a.inventory_item_id = 5716770 and a.job_type='NOT CHILD' then 'PARENT'
when a.job_type='CHILD' and a.inventory_item_id is null then 'CHILD'
when a.job_type='NOT CHILD' and a.inventory_item_id is NOT null then 'NOT CHILD' END JOB_TYPE
from ( select disc2.wip_entity_id as wip_entity_id, decode ( nvl(disc2.attribute9,-1) , -1,'NOT CHILD', 'CHILD') job_type, oel.inventory_item_id
from APPS.wip_discrete_jobs disc2, APPS.oe_order_lines_all oel
where oel.line_id(+) = disc2.source_line_id
)a
where a.wip_entity_id = xx.wip_entity_id
) job_type,
( select decode ( xx.status_type, 6, 'Open',
3, 'Open',
4, 'Completed',
LU1.MEANING )
from APPS.FND_LOOKUP_VALUES LU1
where LU1.LOOKUP_TYPE = 'WIP_JOB_STATUS'
AND LU1.LOOKUP_CODE = xx.STATUS_TYPE
) job_status,
xx.job_released_date,
xx.date_completed,
xx.date_closed
,xx.net_quantity as job_card_qty
,xx.alloy
,xx.profile
,xx.prod_qty_kgs
-- Theoretical Order cost
,xx.cost_kgs_theory
-- Actual Order cost
,xx.cost_kgs_actual
from (
select a.*
-- Theoretical Order cost
, DECODE (a.qty_completed * a.customer_length * a.theoretical_weight,0,0,
a.TOT_THEORY_COST_RELIEVED/(a.qty_completed * a.customer_length * a.theoretical_weight) ) as cost_kgs_theory
-- Actual Order cost
, DECODE ( a.qty_completed * a.customer_length * a.theoretical_weight, 0, 0,
a.TOT_ACTUAL_COST_INCURRED/(a.qty_completed * a.customer_length * a.theoretical_weight )) as cost_kgs_actual
from (
select
-- Normal orders, INTERNAL Orders, Crimped Profile (parent jobs)
-- Sales Order
oeh.order_number as order_number
,oel.line_number
,oel.pricing_quantity_uom as UOM
,oel.attribute1 as customer_length
,oel.attribute6 as theoretical_weight
,oel.attribute5 as finish
,oel.attribute18 as order_qty_pcs
,oel.attribute7 as order_qty_kgs
,xx_om.GetLineUnitSellingPrice(oel.line_id) sales_value
,xx_om.GetHeaderUnitSellingPrice(oeh.header_id) total_value
,oel.ordered_quantity ordered_quantity
-- Production
, tbl0.qty_completed as qty_completed
,disc.wip_entity_id as wip_entity_id
,( select wip_entity_name from APPS.wip_entities ent
where ent.wip_entity_id = disc.wip_entity_id) job_name
,disc.status_type
,disc.date_released as job_released_date
, DECODE ( disc.date_completed, NULL, disc.date_completed,
-- my day Definition
to_date(to_char(to_date(TO_CHAR(disc.date_completed- interval '7' hour,'DD-MON-YYYY')||'00:00:00','DD-MON-YYYY HH24:MI:SS'), 'DD-MON-YYYY HH24:MI:SS'), 'DD-MON-YYYY HH24:MI:SS')) as date_completed
, DECODE ( disc.date_closed, NULL, disc.date_closed,
to_date(to_char(to_date(TO_CHAR(disc.date_closed- interval '7' hour,'DD-MON-YYYY')||'00:00:00','DD-MON-YYYY HH24:MI:SS'), 'DD-MON-YYYY HH24:MI:SS'), 'DD-MON-YYYY HH24:MI:SS')) as date_closed
, disc.net_quantity
, ( select opr2.quantity_completed
from APPS.wip_operations opr2
where opr2.wip_entity_id = disc.wip_entity_id
and opr2.operation_seq_num = (select max(opr.operation_seq_num)
from APPS.wip_operations opr, APPS.wip_discrete_jobs disc2
where opr.wip_entity_id = disc2.wip_entity_id
and disc2.wip_entity_id = disc.wip_entity_id))* oel.attribute1 * oel.attribute6 as prod_qty_kgs
,oel.attribute4 as alloy
,oel.attribute2 as profile
-- Theoretical Order cost
,tbl0.TOT_THEORY_COST_RELIEVED
-- Actual Order cost
,tbl0.TOT_ACTUAL_COST_INCURRED
from XX.XXREPORT_Lzero_TBL tbl0
join APPS.oe_order_headers_all oeh on oeh.header_id = tbl0.header_id
join APPS.oe_order_lines_all oel on oeh.org_id = oel.org_id and oeh.header_id = oel.header_id
join APPS.xx_assemblies asm on oel.line_id = asm.line_id
join APPS.wip_discrete_jobs disc on disc.primary_item_id = asm.inventory_item_id
where oel.link_to_line_id is null
union
-- Crimped Child Jobs
select
-- Sales Order
oeh.order_number as order_number
,oel.line_number
,oel.pricing_quantity_uom as UOM
,oel.attribute1 as customer_length
,oel.attribute6 as theoretical_weight
,oel.attribute5 as finish
,oel.attribute18 as order_qty_pcs
,oel.attribute7 as order_qty_kgs
,xx_om.GetLineUnitSellingPrice(oel.line_id) sales_value
,xx_om.GetHeaderUnitSellingPrice(oeh.header_id) total_value
,oel.ordered_quantity ordered_quantity
-- Production
, tbl0.qty_completed as qty_completed
,child_jobs.wip_entity_id as wip_entity_id
,( select wip_entity_name from APPS.wip_entities ent
where ent.wip_entity_id = child_jobs.wip_entity_id) job_name
,disc.status_type
,disc.date_released as job_released_date
, DECODE ( disc.date_completed, NULL, disc.date_completed,
to_date(to_char(to_date(TO_CHAR(disc.date_completed-interval '7' hour,'DD-MON-YYYY')||'00:00:00','DD-MON-YYYY HH24:MI:SS'), 'DD-MON-YYYY HH24:MI:SS'), 'DD-MON-YYYY HH24:MI:SS')) as date_completed
, DECODE ( disc.date_closed, NULL, disc.date_closed,
to_date(to_char(to_date(TO_CHAR(disc.date_closed-interval '7' hour,'DD-MON-YYYY')||'00:00:00','DD-MON-YYYY HH24:MI:SS'), 'DD-MON-YYYY HH24:MI:SS'), 'DD-MON-YYYY HH24:MI:SS')) as date_closed
, disc.net_quantity
, ( select opr2.quantity_completed
from APPS.wip_operations opr2
where opr2.wip_entity_id = disc.wip_entity_id
and opr2.operation_seq_num = (select max(opr.operation_seq_num)
from APPS.wip_operations opr, APPS.wip_discrete_jobs disc2
where opr.wip_entity_id = disc2.wip_entity_id
and disc.wip_entity_id = disc.wip_entity_id))* oel.attribute1 * oel.attribute6 as prod_qty_kgs
,oel.attribute4 as alloy
,oel.attribute2 as profile
-- Theoretical Order cost
,tbl0.TOT_THEORY_COST_RELIEVED
-- Actual Order cost
,tbl0.TOT_ACTUAL_COST_INCURRED
from XX.XXREPORT_Lzero_TBL tbl0
join APPS.oe_order_headers_all oeh on oeh.header_id = tbl0.header_id
join APPS.oe_order_lines_all oel on oeh.org_id = oel.org_id and oeh.header_id = oel.header_id
join APPS.xx_assemblies asm on oel.line_id = asm.line_id
join APPS.wip_discrete_jobs disc on disc.primary_item_id = asm.inventory_item_id
join ( select wdj2.source_line_id, wdj2.attribute9 child_wip, wdj2.wip_entity_id, wdj2.status_type status_type
from APPS.wip_discrete_jobs wdj2
where attribute9 IS NOT NULL ) child_jobs on child_jobs.child_wip = to_char(disc.wip_entity_id)
where oel.link_to_line_id is null
union
-- Orders with star (*) items need to pick profile and customer length etc from ego_configured_pr_agv view
select
-- Sales Order
oeh.order_number as order_number
,oel.line_number
,oel.pricing_quantity_uom as UOM
,to_char(agv.gx_cp_length) as customer_length
,to_char(agv.gx_cp_th_weight) as theoretical_weight
,agv.gx_cp_surfacetreatment as finish
,oel.attribute18 as order_qty_pcs
, to_char(agv.gx_cp_th_weight * agv.gx_cp_length * oel.ordered_quantity) as order_qty_kgs
,XX.xx_om.GetLineUnitSellingPrice(oel.line_id) sales_value
,XX.xx_om.GetHeaderUnitSellingPrice(oeh.header_id) total_value
,oel.ordered_quantity ordered_quantity
-- Production
, tbl0.qty_completed as qty_completed
,disc.wip_entity_id as wip_entity_id
,( select wip_entity_name from APPS.wip_entities ent
where ent.wip_entity_id = disc.wip_entity_id) job_name
,disc.status_type
,disc.date_released as job_released_date
, DECODE ( disc.date_completed, NULL, disc.date_completed,
to_date(to_char(to_date(TO_CHAR(disc.date_completed-interval '7' hour,'DD-MON-YYYY')||'00:00:00','DD-MON-YYYY HH24:MI:SS'), 'DD-MON-YYYY HH24:MI:SS'), 'DD-MON-YYYY HH24:MI:SS')) as date_completed
, DECODE ( disc.date_closed, NULL, disc.date_closed,
to_date(to_char(to_date(TO_CHAR(disc.date_closed-interval '7' hour,'DD-MON-YYYY')||'00:00:00','DD-MON-YYYY HH24:MI:SS'), 'DD-MON-YYYY HH24:MI:SS'), 'DD-MON-YYYY HH24:MI:SS')) as date_closed
, disc.net_quantity
, ( select opr2.quantity_completed
from APPS.wip_operations opr2
where opr2.wip_entity_id = disc.wip_entity_id
and opr2.operation_seq_num = (select max(opr.operation_seq_num)
from APPS.wip_operations opr, APPS.wip_discrete_jobs disc2
where opr.wip_entity_id = disc2.wip_entity_id
and disc2.wip_entity_id = disc.wip_entity_id))* agv.gx_cp_length * agv.gx_cp_th_weight as prod_qty_kgs
,gx_cp_alloy as alloy
,gx_cp_profile_id as profile
-- Theoretical Order cost
,tbl0.TOT_THEORY_COST_RELIEVED
-- Actual Order cost
,tbl0.TOT_ACTUAL_COST_INCURRED
from XX.XXREPORT_Lzero_TBL tbl0
join APPS.oe_order_headers_all oeh on oeh.header_id = tbl0.header_id
join APPS.oe_order_lines_all oel on oeh.org_id = oel.org_id and oeh.header_id = oel.header_id
join APPS.wip_discrete_jobs disc on oel.line_id = disc.source_line_id
join APPS.ego_gx_configured_pr_agv agv on agv.inventory_item_id= oel.inventory_item_id
where oel.link_to_line_id is null
)a
) xx;
There's almost certainly no short and simple solution to tuning this query. The problem here is it's size and complexity. Lack of performance is merely a consequence.
As a first step I would consider taking a break from the keyboard. Grab a pen and paper and in plain English (or whichever "human" language you prefer) write the questions you want answered from your database via this query. Then ask yourself what columns/variables/attributes do you absolutely need to answer those questions? Write them down as well.
Now, do you really need all of those columns, nested joins, selects, and so forth to produce those variables? Maybe, but probably not. The key point here is to focus on only the data/information you need (YAGNI) and from there map out a picture the bare relationships you need to produce the information that answer your question. In other words, work from the outside in, not the other way around.
I realize that this perhaps sounds a bit abstract and vague, but the whole point is that maintaining clear and simple code is always an ongoing struggle. Keeping your eye on the objective at hand will help keep your head of the weeds.
Finally, a few more specific thoughts at a glance:
Do you really need that union? Try to do without it if you can.
Nesting sucks. Nested nesting especially sucks. Keep things flat whenever possible and practical.
Is it possible or practical to split this into independent, smaller queries?
Use more descriptive names for your variables, add comments judiciously.
Learn and master the SQL EXPLAIN command.

Oracle 'CONNECT BY' Syntax

This is an offshoot of the following question:
Single out duplicates between two result sets
As by a comment in that questions, I'm trying to implement my query using Oracle's special 'CONNECT BY' syntax. I'm having trouble finding any (clear) information on how to implement the syntax in my case.
My query:
SELECT pi.compressed_name, pi.phn, to_char(pi.date_of_birth , 'YYYY/MM/DD') as date_of_birth,
to_char(pe.started_on , 'YYYY/MM/DD' ) as medicare_eligibility_start,
to_char(pe.ended_on , 'YYYY/MM/DD' ) as medicare_eligibility_end
FROM medcrtr.forest_node fnpppp,
medcrtr.forest_node fnppp,
medcrtr.forest_node fnpp,
medcrtr.forest_node fnp,
medcrtr.forest_node fn,
medcrtr.group_member gm,
medcrtr.program_eligibility pe,
person_index pi
WHERE gm.entity_type_id = 1
AND fn.source_id = gm.group_id
AND fn.entity_type_id = 3
AND fnp.id = fn.parent_id
AND fnpp.id = fnp.parent_id
AND fnppp.id = fnpp.parent_id
AND fnpppp.id = fnppp.parent_id
AND pe.person_id = gm.source_id
AND pe.sub_program_id = fnpp.parent_id
AND pi.person_id = gm.source_id
AND fnppp.id = 1169
AND (gm.ended_on >= SYSDATE OR gm.ended_on IS NULL)
Can anyone point me in the right direction to get it converted to the different syntax?
I'm thinking something along the lines of:
SELECT pi.compressed_name, pi.phn, to_char(pi.date_of_birth , 'YYYY/MM/DD') as date_of_birth,
to_char(pe.started_on , 'YYYY/MM/DD' ) as medicare_eligibility_start,
to_char(pe.ended_on , 'YYYY/MM/DD' ) as medicare_eligibility_end
FROM medcrtr.forest_node fn,
group_member gm,
program_eligibility pe,
person_index pi
WHERE gm.entity_type_id = 1
AND fn.source_id = gm.group_id
AND fn.entity_type_id = 3
AND pe.person_id = gm.source_id
--AND pe.sub_program_id = fnpp.parent_id ???
AND pi.person_id = gm.source_id
--AND fnppp.id = 1169 ???
AND (gm.ended_on >= SYSDATE OR gm.ended_on IS NULL)
CONNECT BY PRIOR fn.id=fn.parent_id
This is not working obviously, and I don't know how to integrate the functionality of the fnpp...'s yet.Any help?
I'm not sure but I think you're missing the start with clause:
SELECT pi.compressed_name, pi.phn, to_char(pi.date_of_birth , 'YYYY/MM/DD') as date_of_birth,
to_char(pe.started_on , 'YYYY/MM/DD' ) as medicare_eligibility_start,
to_char(pe.ended_on , 'YYYY/MM/DD' ) as medicare_eligibility_end
FROM medcrtr.forest_node fn,
group_member gm,
program_eligibility pe,
person_index pi
WHERE gm.entity_type_id = 1
AND fn.source_id = gm.group_id
AND fn.entity_type_id = 3
AND pe.person_id = gm.source_id
AND pi.person_id = gm.source_id
AND (gm.ended_on >= SYSDATE OR gm.ended_on IS NULL)
start with fn.id = 1169 /*THis is where the recursion will start */
CONNECT BY PRIOR prior fn.id=fn.parent_id /*specify you want the current node's parent id to match the previous node's id*/
A good reference: http://www.adp-gmbh.ch/ora/sql/connect_by.html