I have three tables using complex. I run them separately without problems. Here are the queries:
TABLE A:
select
maxxx.id_demande_diffusion AS ID_DIFFUSION,
maxxx.id_notification as ID_NOTIFICATION,
maxxx.cd_organisation_client as ID_ENTITE,
maxxx.cod_entrep as ID_ENTITE_GARANTE,
maxxx.cd_canal as CD_CANAL,
maxxx.id_demande_diffusion_originale as ID_DIFFUSION_PARENT,
maxxx.ref_maquette as REF_MAQUETTE,
maxxx.qualification_canal as QUALIFICATION_CANAL,
maxxx.ger_id_pli as ID_PLI_GER,
case when maxxx.typ_mvt="S" then 1 else 0 end AS TOP_SUPP,
case when maxxx.typ_mvt = "S" then to_date(substr(maxxx.dt_capt, 1, 11)) else null end AS DT_SUPP,
minnn.typ_mvt as MIN_MVT,
maxxx.typ_mvt as MAX_MVT,
case when minnn.typ_mvt = 'C' then 'C' else 'M' end as TYP_MVT
from
(select s.id_demande_diffusion, s.dt_capt, s.typ_mvt from ${use_database}.pz_send_demande_diffusion as s
join
(select id_demande_diffusion, min(dt_capt) as dtmin from ${use_database}.pz_send_demande_diffusion group by id_demande_diffusion) as minn
on minn.id_demande_diffusion=s.id_demande_diffusion and s.dt_capt=minn.dtmin ) as minnn
join
(select s.id_demande_diffusion, s.typ_mvt, s.id_notification, s.dt_capt, s.cd_organisation_client, s.cod_entrep, s.cd_canal, s.id_demande_diffusion_originale,
s.ref_maquette, s.qualification_canal, s.ger_id_pli from ${use_database}.pz_send_demande_diffusion as s
join
(select id_demande_diffusion, max(dt_capt) as dtmax from ${use_database}.pz_send_demande_diffusion group by id_demande_diffusion) as maxx
on s.id_demande_diffusion=maxx.id_demande_diffusion and s.dt_capt=maxx.dtmax)as maxxx
on minnn.id_demande_diffusion=maxxx.id_demande_diffusion;
TABLE B:
select
maxxx.id_notification as ID_NOTIFICATION,
maxxx.cd_type_destinataire as CD_TYPE_DESTINATAIRE,
case when maxxx.cd_type_destinataire = "IDGRC" then maxxx.destinataire else null end AS ID_PERSONNE,
case when maxxx.cd_type_destinataire = "MAIL" then maxxx.destinataire else null end AS EMAIL_DESTINATAIRE,
case when maxxx.cd_type_destinataire = "SMS" then maxxx.destinataire else null end AS NUM_TEL_DESTINATAIRE,
maxxx.cd_type_evenement,
maxxx.cd_type_notification,
maxxx.cd_type_destinataire_source AS CD_TYPE_DEST_SOURCE,
case when maxxx.cd_type_destinataire_source = "IDGRC" then maxxx.destinataire_source when maxxx.cd_type_destinataire_source = "IDGRC|IDGRC" then substr(maxxx.destinataire_source, 1, locate("|", maxxx.destinataire_source)-1) else null end AS ID_PERS_DEST_SOURCE,
case when maxxx.cd_type_destinataire_source = "SIGMA" or maxxx.cd_type_destinataire_source = "CUBA" then maxxx.destinataire_source else null end AS REF_EXT_DEST_SOURCE,
case when maxxx.cd_type_destinataire_source = "MAIL" then maxxx.destinataire_source else null end AS EMAIL_DEST_SOURCE,
case when maxxx.cd_type_destinataire_source = "SMS" then maxxx.destinataire_source else null end AS NUM_TEL_DEST_SOURCE,
case when maxxx.cd_type_destinataire_source = "IDGRC|IDGRC" then substr(maxxx.destinataire_source, locate("|", maxxx.destinataire_source)+1, length(maxxx.destinataire_source)) end AS ID_PERSONNE_DEST_SOURCE_2
from
(select n.id_notification, n.destinataire, n.cd_type_evenement, n.cd_type_notification, n.destinataire_source, n.cd_type_destinataire, n.cd_type_destinataire_source from ${use_database}.pz_send_notification as n
join
(select id_notification, max(dt_capt) as dtmax from ${use_database}.pz_send_notification group by id_notification) as maxx
on n.id_notification=maxx.id_notification and n.dt_capt=maxx.dtmax) as maxxx;
TABLE C:
select
maxxx.id_communication AS ID_COMMUNICATION,
maxxx.cd_sa as CD_SYS_DIFFUSEUR,
maxxx.type_conteneur as CD_TYPE_CONTENEUR
from
(select n.id_communication, n.cd_sa, n.type_conteneur from ${use_database}.pz_send_comm_retour as n
join
(select id_communication, max(dt_capt) as dtmax from ${use_database}.pz_send_comm_retour group by id_communication) as maxx
on n.id_communication=maxx.id_communication and n.dt_capt=maxx.dtmax) as maxxx;
Is there anyway to combine the three of the using one join and one left join ?
I want o have something like
SELECT * FROM (TABLE A join TABLE B ON A.ID_NOTIFICATION=B.ID_NOTIFICATION) AS TMP LEFT JOIN TABLE C ON TMP.ID_DIFFUSION=C.ID_COMMUNICATION;
I have been trying but it always fails because of missing or misplaced parenthesis.
Thank you!
I have no idea if your queries are correct, but common table expressions (CTE) can frequently be used to keep result set joins clean.
WITH TABLE_A AS
( SELECT
FROM ...
...
),
TABLE_B AS
( SELECT
FROM ...
...
),
TABLE_C AS
( SELECT
FROM ...
...
)
SELECT *
FROM TABLE_A TA
JOIN TABLE_B TB
ON TA.Key_Field = TB.Key_Field
JOIN TABLE_C TC
ON TB.Key_Field = TC.Key_Field
#DRapp - Revised query below: I need help in optimizing a Oracle/SQL query to run for more than 2 weeks of data. it works for 2 weeks of data then chokes. I inherited this. All the business rules need to stay, but is there a way I can simplify this so it will work for a larger data set? Specific examples and tips would be appreciated. This can be broken down into several queries, but needs to return the same results back. thanks for your help.
Oracle SQL Query code is as follows:
SELECT '1' AS group1,
usr.USR_NAME,
rec.USR_UID_USER,
rec.REC_DATE_PAID,
TO_CHAR(rec.REC_DATE_PAID, 'MM/DD/YYYY (fmDay)') AS group_date,
rec.REC_AMOUNT,
rec.REC_UID,
rec.REG_UID_RECEIPT_GROUP,
rec.REC_TAX1_AMOUNT,
rec.REC_TAX2_AMOUNT,
rec.REC_TAX3_AMOUNT,
rec.REC_AMOUNT - (
CASE
WHEN NVL2(dis.SUMDIS, dis.SUMDIS, 0) <> 0
THEN NVL(Fit2Sum.SumAmt, 0)
ELSE 0
END) - rec.REC_TAX1_AMOUNT - rec.REC_TAX2_AMOUNT - rec.REC_TAX3_AMOUNT
AS "GrossRevAmountnoTax",
rec.REC_AMOUNT,
-(
CASE
WHEN NVL2(dis.SUMDIS, dis.SUMDIS, 0) <> 0
THEN NVL(Fit2Sum.SumAmt, 0)
ELSE 0
END)
AS "GrossRevAmountwTax",
rec.REC_AMOUNT - rec.REC_TAX1_AMOUNT - rec.REC_TAX2_AMOUNT - rec.REC_TAX3_AMOUNT
AS "NetRevenueAmount",
(
CASE
WHEN NVL(FitGrace.GraceAmount, 0) = 0
THEN 1
ELSE 0
END) AS "IsGrace",
(
CASE
WHEN NVL(dis.DIS_UID, 0) = 10
THEN NVL(dis.SUMDIS, 0)
ELSE 0
END) AS "TicoAmount",
(
CASE
WHEN NVL(dis.DIS_UID, 0) = 10
THEN 1
ELSE 0
END) AS "TicoCount",
(
CASE
WHEN NVL(dis.DIS_UID, 0) NOT IN (10, 0)
THEN NVL(dis.SUMDIS, 0)
ELSE 0
END) AS "ValidationAmount",
(
CASE
WHEN NVL(dis.DIS_UID, 0) NOT IN (10, 0)
THEN 1
ELSE 0
END) AS "ValidationCount",
(
CASE
WHEN NVL(PRFGrp.PSMCount, 0) > 1
THEN 'Central Cashier Station'
ELSE TO_CHAR(PRFGrp.MaxFacDescription)
END) AS "FacilityDescription",
(
CASE
WHEN NVL(PRFGrp.PSMCount, 0) > 1
THEN 0
ELSE MAX(PRFGrp.FAC_UID_FACILITY)
END) AS "FacilityUID",
dis.DIS_DESCRIPTION "DiscountDescription",
NVL(dis.countdis, 0) "ValCount",
NVL(dis.SUMDIS, 0) "ValAmount",
NVL(dis.DIS_UID, 0) "DiscountUID",
dis.VLDNUM "ValidationNumber",
dis.THI_NAME "ValidationThirdParty",
dis.VTE_DESCRIPTION "ValidationControlGroup",
pmm.PMM_DESCRIPTION,
pmm.PMM_UID,
pmm.PAY_UID_PAYMENT_TYPE,
psm.PSM_DESCRIPTION,
pol.POL_DESCRIPTION,
cas.CAS_UID,
cas.CAS_OPEN_DATE,
cas.CAS_CLOSE_DATE,
MAX(fit.FIT_SALE_ITEM_DESCRIPTION) AS SaleItem,
NVL(per.PER_NUMBER, rtx.RTX_REPLACEMENT_NUMBER) AS TicketNumber,
rtx.RTX_REPLACEMENT_NUMBER AS ReplacementNumber,
NVL(ptx.PTX_DATE_ENTRY, ptx2.PTX_DATE_ENTRY) AS "EntryTime",
NVL(ptx.PTX_DATE_EXIT, ptx2.PTX_DATE_EXIT) AS "ExitTime",
(TO_CHAR(TRUNC(NVL(ptx.PTX_DATE_EXIT, ptx2.PTX_DATE_EXIT) - NVL(ptx.PTX_DATE_ENTRY,
ptx2.PTX_DATE_ENTRY)))
|| 'd '
|| TO_CHAR(mod(TRUNC((NVL(ptx.PTX_DATE_EXIT, ptx2.PTX_DATE_EXIT) - NVL(ptx.PTX_DATE_ENTRY,
ptx2.PTX_DATE_ENTRY)) * 24), 24))
|| 'h '
|| TO_CHAR(mod(TRUNC((NVL(ptx.PTX_DATE_EXIT, ptx2.PTX_DATE_EXIT) - NVL(ptx.PTX_DATE_ENTRY,
ptx2.PTX_DATE_ENTRY)) * 24 * 60), 60))
|| 'm '
|| TO_CHAR(mod(TRUNC((NVL(ptx.PTX_DATE_EXIT, ptx2.PTX_DATE_EXIT) - NVL(ptx.PTX_DATE_ENTRY,
ptx2.PTX_DATE_ENTRY)) * 24 * 60 * 60), 60))
|| 's') AS "TimeElapsed",
NVL(ptx.LAN_UID_ENTRY, ptx2.LAN_UID_ENTRY) AS "EntryLaneUID",
NVL(ptx.LAN_UID_EXIT, ptx2.LAN_UID_EXIT) AS "ExitLaneUID",
MAX(
(SELECT lan.LAN_DESCRIPTION
FROM lane lan
WHERE lan.LAN_UID = NVL(ptx.LAN_UID_ENTRY, ptx2.LAN_UID_ENTRY)
)) AS "EntryLaneDesc",
MAX(
(SELECT lan.LAN_DESCRIPTION
FROM lane lan
WHERE lan.LAN_UID = NVL(ptx.LAN_UID_EXIT, ptx2.LAN_UID_EXIT)
)) AS "ExitLaneDesc",
crc.CRC_LAST_FOUR,
ctr.CTR_CONFIRMATION_CODE,
ctr.CTR_RETURN_CODE,
ctr.CTR_RETURN_MESSAGE,
ctr.CTR_TRAN_GUID,
ctr.CTR_AUTHORIZATION_REQUEST_DATE,
ctr.CTR_SUCCESS,
ctr.CTR_TRANSACTION_DATE
FROM RECEIPT rec
INNER JOIN USER_ACCOUNT usr
ON rec.USR_UID_USER = usr.USR_UID
INNER JOIN PAYMENT_METHOD_MLKP pmm
ON rec.PMM_UID_PAYMENT_METHOD = pmm.PMM_UID
INNER JOIN financial_transaction fit
ON rec.REC_UID = fit.REC_UID_RECEIPT
LEFT JOIN permission per
ON fit.FIT_SOURCE_OBJ_UID = per.PER_UID
AND fit.TAB_UID_SOURCE_OBJ_TYPE = 10
LEFT JOIN parking_transaction ptx
ON per.PER_UID = ptx.PER_UID_PERMISSION
AND ptx.PTT_UID_TYPE <> 17
LEFT JOIN replacement_transaction rtx
ON fit.FIT_SOURCE_OBJ_UID = rtx.RTX_UID
AND fit.TAB_UID_SOURCE_OBJ_TYPE = 332
LEFT JOIN parking_transaction ptx2
ON rtx.RTX_UID = ptx2.RTX_UID_REPLACEMENT_TRANS
AND ptx.PTT_UID_TYPE <> 17
LEFT JOIN
(SELECT dis.DIS_DESCRIPTION,
dis.DIS_UID,
vte.VTE_DESCRIPTION,
fit2.FIT_UID AS countdis,
fit2.FIT_AMOUNT AS SUMDIS,
vld.VLD_VALIDATION_NUMBER AS VLDNUM,
thi.THI_NAME,
fit2.FIT_UID_PAY_ADJ_REV_ITEM
FROM financial_transaction fit2
INNER JOIN discount_mlkp dis
ON fit2.DIS_UID_DISCOUNT = dis.DIS_UID
LEFT JOIN validation vld
ON fit2.VLD_UID_VALIDATION = vld.VLD_UID
LEFT JOIN enc_print_history esp
ON vld.ESP_UID_PRINT_ID = esp.ESP_UID
LEFT JOIN third_party thi
ON esp.THI_UID_THIRD_PARTY = thi.THI_UID
LEFT JOIN validation_control_group vte
ON vld.VTE_UID_VALIDATION_CTRL_GRP = vte.VTE_UID
WHERE fit2.DIS_UID_DISCOUNT <> 0
) dis ON fit.FIT_UID_PAY_ADJ_REV_ITEM = dis.FIT_UID_PAY_ADJ_REV_ITEM
AND rec.REC_UID =
(SELECT MIN(rec2.REC_UID)
FROM receipt rec2
INNER JOIN receipt_group reg
ON rec2.REG_UID_RECEIPT_GROUP = reg.REG_UID
WHERE rec.REG_UID_RECEIPT_GROUP = reg.REG_UID
)
LEFT JOIN
(SELECT fit2.FIT_UID_PAY_ADJ_REV_ITEM,
SUM(fit2.FIT_AMOUNT) AS SumAmt
FROM financial_transaction fit2
WHERE fit2.DIS_UID_DISCOUNT <> 0
GROUP BY fit2.FIT_UID_PAY_ADJ_REV_ITEM
) Fit2Sum
ON fit.FIT_UID_PAY_ADJ_REV_ITEM = Fit2Sum.FIT_UID_PAY_ADJ_REV_ITEM
LEFT JOIN
(SELECT fit2.FIT_UID,
SUM(fit2.FIT_AMOUNT) AS GraceAmount
FROM financial_transaction fit2
GROUP BY fit2.FIT_UID
) FitGrace
ON fit.FIT_UID_PAY_ADJ_REV_ITEM = FitGrace.FIT_UID
INNER JOIN cashdrawer_session cas
ON rec.CAS_UID_CASHDRAWER_SESSION = cas.CAS_UID
INNER JOIN pos_station psm
ON cas.PSM_UID_STATION = psm.PSM_UID
INNER JOIN pos_station_type_lkp pol
ON psm.POL_UID_STATION_TYPE = pol.POL_UID
LEFT JOIN
(SELECT pfr.PSM_UID_STATION,
COUNT(*) AS PSMCount,
MAX(fac.FAC_DESCRIPTION) AS MaxFacDescription,
pfr.FAC_UID_FACILITY
FROM pos_facility_rel pfr
INNER JOIN facility fac
ON pfr.FAC_UID_FACILITY = fac.FAC_UID
GROUP BY pfr.PSM_UID_STATION,
pfr.FAC_UID_FACILITY
) PRFGrp ON psm.PSM_UID = PRFGrp.PSM_UID_STATION
LEFT JOIN ctr_rec_rel crr
ON rec.REC_UID = crr.REC_UID_RECEIPT
LEFT JOIN credit_card_transaction ctr
ON crr.CTR_UID_CREDIT_CARD_TRANS = ctr.CTR_UID
LEFT JOIN credit_card crc
ON ctr.CRC_UID_PROCESSED = crc.CRC_UID
WHERE pmm.PMM_UID <> 12
GROUP BY usr.USR_NAME,
rec.USR_UID_USER,
rec.REC_DATE_PAID,
TO_CHAR(rec.REC_DATE_PAID, 'MM/DD/YYYY (fmDay)'),
rec.REC_AMOUNT,
rec.REC_UID,
rec.REG_UID_RECEIPT_GROUP,
rec.REC_TAX1_AMOUNT,
rec.REC_TAX2_AMOUNT,
rec.REC_TAX3_AMOUNT,
dis.DIS_DESCRIPTION,
dis.VLDNUM,
dis.THI_NAME,
dis.VTE_DESCRIPTION,
pmm.PMM_DESCRIPTION,
pmm.PMM_UID,
pmm.PAY_UID_PAYMENT_TYPE,
psm.PSM_DESCRIPTION,
pol.POL_DESCRIPTION,
cas.CAS_UID,
cas.CAS_OPEN_DATE,
cas.CAS_CLOSE_DATE,
NVL(per.PER_NUMBER, rtx.RTX_REPLACEMENT_NUMBER),
rtx.RTX_REPLACEMENT_NUMBER,
NVL(ptx.PTX_DATE_ENTRY, ptx2.PTX_DATE_ENTRY),
NVL(ptx.PTX_DATE_EXIT, ptx2.PTX_DATE_EXIT),
NVL(ptx.LAN_UID_ENTRY, ptx2.LAN_UID_ENTRY),
NVL(ptx.LAN_UID_EXIT, ptx2.LAN_UID_EXIT),
crc.CRC_LAST_FOUR,
ctr.CTR_CONFIRMATION_CODE,
ctr.CTR_RETURN_CODE,
ctr.CTR_RETURN_MESSAGE,
ctr.CTR_TRAN_GUID,
ctr.CTR_AUTHORIZATION_REQUEST_DATE,
ctr.CTR_SUCCESS,
ctr.CTR_TRANSACTION_DATE,
fit.FIT_UID_PAY_ADJ_REV_ITEM,
dis.countdis,
dis.SUMDIS,
dis.DIS_UID,
psm.PSM_UID,
(rec.REC_AMOUNT - rec.REC_TAX1_AMOUNT - rec.REC_TAX2_AMOUNT - rec.REC_TAX3_AMOUNT)
If you see a step change in performance (rather than just a linear change in query duration relative to the date range), it's likely to be due to one of three issues:
A change in the query optimisation, which you can check with an execution plan. http://docs.oracle.com/cd/E11882_01/appdev.112/e25788/d_xplan.htm
An increase in the data volume causing a sort operation to switch from optimal to one-pass, or from one-pass to multipass, which you can check by using v$sql_workarea http://docs.oracle.com/cd/E11882_01/server.112/e40402/dynviews_3061.htm#REFRN30256
A change in the "rate" of data -- for example, if you went from 10,000 records per day to 50,000.
These would be the first issues I'd check.
Aside from cleaning (format) of the query to see better what is going on, I made a few small changes. You had a few columns that were based on select count(*) or similar based on whatever the current "fit" record was. From the sounds of your data, that is killing the system some. I've moved those out to three separate LEFT-JOINs to the respective tables (Fit2Sum and FitGrace linked to FIT, and PRFGrp is linked via psm alias).
Now, that said, and I dont know how large volume your tables are, you MAY want to put some limit if there are any date/time fields there that you can restrict (such as only for a month of data...). But, by pre-querying those vs being done on every record COULD be an impact that is killing your process.
SELECT
'1' AS group1,
usr.USR_NAME,
rec.USR_UID_USER,
rec.REC_DATE_PAID,
TO_CHAR(rec.rec_date_paid,'MM/DD/YYYY (fmDay)') AS group_date,
rec.rec_amount,
rec.rec_uid,
rec.reg_uid_receipt_group,
rec.rec_tax1_amount,
rec.rec_tax2_amount,
rec.rec_tax3_amount,
MAX( rec.rec_amount -
- CASE WHEN NVL2( dis.sumdis, dis.sumdis,0) <> 0
THEN NVL( Fit2Sum.SumAmt, 0 )
ELSE 0 END
- rec.rec_tax1_amount
- rec.rec_tax2_amount
- rec.rec_tax3_amount ) AS "GrossRevAmountNoTax",
MAX( rec.rec_amount
- CASE WHEN NVL2(dis.sumdis,dis.sumdis,0) <> 0
THEN NVL( Fit2Sum.SumAmt, 0 )
ELSE 0 END ) AS "GrossRevAmountwTax",
MAX( rec.REC_AMOUNT
- rec.rec_tax1_amount
- rec.rec_tax2_amount
- rec.rec_tax3_amount ) AS "NetRevenueAmount",
MAX( CASE WHEN NVL( FitGrace.GraceAmount, 0 ) = 0
THEN 1
ELSE 0 END) AS "IsGrace",
/*Grace tickets have original fee amount of 0*/
MAX( CASE WHEN NVL(dis.dis_uid,0) = 10
THEN NVL(dis.sumdis,0)
ELSE 0 END ) AS "TicoAmount",
/*dis_uid = 10 is TICO*/
MAX( CASE WHEN NVL(dis.dis_uid,0) = 10
THEN 1
ELSE 0 END ) AS "TicoCount",
MAX( CASE WHEN NVL(dis.dis_uid,0) NOT IN (10,0)
THEN NVL(dis.sumdis,0)
ELSE 0 END ) AS "ValidationAmount",
MAX( CASE WHEN NVL(dis.dis_uid,0) NOT IN (10,0)
THEN 1
ELSE 0 END ) AS "ValidationCount",
MAX( CASE WHEN NVL( PRFGrp.PSMCount, 0 ) > 1
THEN 'Central Cashier Station'
ELSE TO_CHAR(PRFGrp.MaxFacDescription) END ) AS "FacilityDescription",
/*pulls the facility description or Central Cashier Station if a central cashier station*/
MAX( CASE WHEN NVL( PRFGrp.PSMCount, 0 ) > 1
THEN 0
ELSE MAX(PRFGrp.fac_uid_facility) END ) AS "FacilityUID",
dis.dis_description "DiscountDescription",
NVL(dis.countdis,0) "ValCount",
NVL(dis.sumdis,0) "ValAmount",
NVL(dis.dis_uid,0) "DiscountUID",
dis.VLDNUM "ValidationNumber",
dis.thi_name "ValidationThirdParty",
dis.vte_description "ValidationControlGroup",
pmm.PMM_DESCRIPTION,
pmm.pmm_uid,
pmm.pay_uid_payment_type,
psm.psm_description,
pol.pol_description,
cas.cas_uid,
cas.cas_open_date,
cas.cas_close_date,
MAX(fit.fit_sale_item_description) AS SaleItem,
NVL(per.per_number, rtx.rtx_replacement_number) AS TicketNumber,
rtx.rtx_replacement_number AS ReplacementNumber,
NVL(ptx.ptx_date_entry, ptx2.ptx_date_entry) AS "EntryTime",
NVL(ptx.ptx_date_exit, ptx2.ptx_date_exit) AS "ExitTime",
MAX(( TO_CHAR( TRUNC( NVL(ptx.ptx_date_exit, ptx2.ptx_date_exit)
-NVL(ptx.ptx_date_entry, ptx2.ptx_date_entry)))||'d '||
TO_CHAR(mod(TRUNC(( NVL(ptx.ptx_date_exit, ptx2.ptx_date_exit)
-NVL(ptx.ptx_date_entry, ptx2.ptx_date_entry))*24),24))||'h '||
TO_CHAR(mod(TRUNC(( NVL(ptx.ptx_date_exit, ptx2.ptx_date_exit)
-NVL(ptx.ptx_date_entry, ptx2.ptx_date_entry))*24*60),60))||'m '||
TO_CHAR(mod(TRUNC(( NVL(ptx.ptx_date_exit,ptx2.ptx_date_exit)
-NVL(ptx.ptx_date_entry,ptx2.ptx_date_entry))*24*60*60),60))||'s')) AS "TimeElapsed",
/*pulls the time between entry/exit in DD HH MM SS format*/
NVL(ptx.lan_uid_entry, ptx2.lan_uid_entry) AS "EntryLaneUID",
NVL(ptx.lan_uid_exit, ptx2.lan_uid_exit) AS "ExitLaneUID",
MAX( ( SELECT lan.lan_description
FROM lane lan
WHERE lan.lan_uid = NVL(ptx.lan_uid_entry, ptx2.lan_uid_entry))) AS "EntryLaneDesc",
MAX( ( SELECT lan.lan_description
FROM lane lan
WHERE lan.lan_uid = NVL(ptx.lan_uid_exit, ptx2.lan_uid_exit))) AS "ExitLaneDesc",
crc.crc_last_four,
ctr.ctr_confirmation_code,
ctr.ctr_return_code,
ctr.ctr_return_message,
ctr.ctr_tran_guid,
ctr.ctr_authorization_request_date,
ctr.ctr_success,
ctr.ctr_transaction_date
FROM
RECEIPT rec
INNER JOIN USER_ACCOUNT usr
ON rec.USR_UID_USER = usr.USR_UID
INNER JOIN PAYMENT_METHOD_MLKP pmm
ON rec.PMM_UID_PAYMENT_METHOD = pmm.PMM_UID
INNER JOIN financial_transaction fit
ON rec.rec_uid = fit.rec_uid_receipt
LEFT JOIN permission per
ON fit.fit_source_obj_uid = per.per_uid
AND fit.tab_uid_source_obj_type = 10
LEFT JOIN parking_transaction ptx
ON per.per_uid = ptx.per_uid_permission
AND ptx.ptt_uid_type <> 17
LEFT JOIN replacement_transaction rtx
ON fit.fit_source_obj_uid = rtx.rtx_uid
AND fit.tab_uid_source_obj_type = 332
LEFT JOIN parking_transaction ptx2
ON rtx.rtx_uid = ptx2.rtx_uid_replacement_trans
AND ptx.ptt_uid_type <> 17
LEFT JOIN ( SELECT
dis.dis_description,
dis.dis_uid,
vte.vte_description,
fit2.fit_uid AS countdis,
fit2.fit_amount AS SUMDIS,
vld.vld_validation_number AS "VLDNUM",
thi.thi_name,
fit2.fit_uid_pay_adj_rev_item
FROM
financial_transaction fit2
INNER JOIN discount_mlkp dis
ON fit2.dis_uid_discount = dis.dis_uid
LEFT JOIN validation vld
ON fit2.vld_uid_validation = vld.vld_uid
LEFT JOIN enc_print_history esp
ON vld.esp_uid_print_id = esp.esp_uid
LEFT JOIN third_party thi
ON esp.thi_uid_third_party = thi.thi_uid
LEFT JOIN validation_control_group vte
ON vld.vte_uid_validation_ctrl_grp = vte.vte_uid
WHERE
fit2.dis_uid_discount <> 0) dis
ON fit.fit_uid_pay_adj_rev_item = dis.fit_uid_pay_adj_rev_item
AND rec.rec_uid = ( SELECT MIN(rec2.rec_uid)
FROM receipt rec2
INNER JOIN receipt_group reg
ON rec2.reg_uid_receipt_group = reg.reg_uid
WHERE rec.reg_uid_receipt_group = reg.reg_uid)
/*
this is grabbing the detail of any validations used during the transaction. If more then one
validation is used per transient, it will pull the transient permit record multiple times
(equal to the number of validations used). This is by design so we can get the detail info,
must account for these potential duplicates within report using running totals- Added logic to
account for split payments, case statement forces the validation info to only show for the
first receipt of the receipt group- JB21213
*/
LEFT JOIN ( select
fit2.fit_uid_pay_adj_rev_item,
SUM( fit2.fit_amount ) as SumAmt
from
financial_transaction fit2
where
fit2.dis_uid_discount <> 0
group by
fit2.fit_uid_pay_adj_rev_item ) Fit2Sum
ON fit.fit_uid_pay_adj_rev_item = Fit2Sum.fit_uid_pay_adj_rev_item
LEFT JOIN ( SELECT
fit2.fit_uid,
SUM(fit2.fit_amount) as GraceAmount
FROM
financial_transaction fit2
GROUP BY
fit2.fit_uid ) FitGrace
ON fit.fit_uid_pay_adj_rev_item = FitGrace.fit_uid
INNER JOIN cashdrawer_session cas
ON rec.cas_uid_cashdrawer_session = cas.cas_uid
INNER JOIN pos_station psm
ON cas.psm_uid_station = psm.psm_uid
INNER JOIN pos_station_type_lkp pol
ON psm.pol_uid_station_type = pol.pol_uid
LEFT JOIN ( select
prf.psm_uid_station,
COUNT(*) as PSMCount,
MAX(fac.fac_description) as MaxFacDescription
from
pos_facility_rel pfr
INNER JOIN facility fac
ON pfr.fac_uid_facility = fac.fac_uid
group by
prf.psm_uid_station ) PRFGrp
ON psm.psm_uid = PRFGrp.psm_uid_station
LEFT JOIN ctr_rec_rel crr
ON rec.rec_uid = crr.rec_uid_receipt
LEFT JOIN credit_card_transaction ctr
ON crr.ctr_uid_credit_card_trans = ctr.ctr_uid
LEFT JOIN credit_card crc
ON ctr.crc_uid_processed = crc.crc_uid
WHERE
pmm.pmm_uid <> 12
GROUP BY
usr.USR_NAME,
rec.USR_UID_USER,
rec.REC_DATE_PAID,
rec.REC_AMOUNT,
rec.rec_tax1_amount,
rec.rec_tax2_amount,
rec.rec_tax3_amount,
pmm.PMM_DESCRIPTION,
rec.rec_uid,
rec.reg_uid_receipt_group,
psm.psm_description,
cas.cas_uid,
cas.cas_open_date,
cas.cas_close_date,
fit.fit_uid_pay_adj_rev_item,
dis.dis_description,
dis.countdis,
dis.sumdis,
dis.VLDNUM,
dis.dis_uid,
dis.thi_name,
dis.vte_description,
pmm.pay_uid_payment_type,
psm.psm_uid,
pol.pol_description,
pmm.pmm_uid,
TO_CHAR(rec.rec_date_paid,'MM/DD/YYYY (fmDay)'),
NVL(per.per_number,rtx.rtx_replacement_number),
rtx.rtx_replacement_number,
NVL(ptx.ptx_date_entry,ptx2.ptx_date_entry),
NVL(ptx.ptx_date_exit,ptx2.ptx_date_exit),
NVL(ptx.lan_uid_entry,ptx2.lan_uid_entry),
NVL(ptx.lan_uid_exit,ptx2.lan_uid_exit),
crc.crc_last_four,
ctr.ctr_confirmation_code,
ctr.ctr_return_code,
ctr.ctr_return_message,
ctr.ctr_tran_guid,
ctr.ctr_authorization_request_date,
ctr.ctr_success,
ctr.ctr_transaction_date,
(rec.rec_amount
- rec.rec_tax1_amount
- rec.rec_tax2_amount
- rec.rec_tax3_amount );
QUERY CLARIFICATION...
To help understand what is going on with the revised query. On several of the fields, you were running the same query multiple times getting a COUNT(*) based on whatever was the "current" ID, being some facility, person, whatever. If you do that query at the field level, it runs those queries EACH TIME per column, per row...
What I have done was to do a SINGLE pre-aggregation on each respective per facility, person, whatever for those other aliases (such as Fit2Sum, FitGrace, PRFGrp). While keeping the respective "ID" as the group by column in those result sets, the LEFT-JOIN points to one record in each respective set based on that JOIN criteria.
Now, the case/when construct. Since the pre-aggregations have already been performed, and the join is per the respective "ID" column, you no longer need the COUNT() for each column, just grab the final column name from the pre-aggregation query and test that. If the record is found and has a count, do the same as your original COUNT(). In some case, it would return an ID, others, return 0. So, for your example of "GrossRevAmountnoTax",
rec.rec_amount-(CASE WHEN NVL2(dis.sumdis,dis.sumdis,0) <> 0
THEN
(SELECT SUM(fit2.fit_amount)
FROM financial_transaction fit2
WHERE fit.fit_uid_pay_adj_rev_item = fit2.fit_uid_pay_adj_rev_item
AND fit2.dis_uid_discount <> 0)
ELSE 0
END)-rec.rec_tax1_amount-rec.rec_tax2_amount-rec.rec_tax3_amount
AS "GrossRevAmountnoTax",
you are selecting the sum() of the fit_amount based on the fit_uid_pay_adj_rev_item. Since I prequeried this into the Fit2Sum alias, the join is on the fit_uid_pay_adj_rev_item and am just grabbing that column (Fit2Sum.SumAmt) so the query does NOT have to be done repeatedly.
rec.rec_amount -
- CASE WHEN NVL2( dis.sumdis, dis.sumdis,0) <> 0
THEN NVL( Fit2Sum.SumAmt, 0 )
ELSE 0 END
- rec.rec_tax1_amount
- rec.rec_tax2_amount
- rec.rec_tax3_amount AS "GrossRevAmountnoTax",
Again, since it is already sitting at the record in Fit2Sum alias, it can immediately follow with
rec.rec_amount-(CASE WHEN NVL2(dis.sumdis,dis.sumdis,0) <> 0
THEN
(SELECT SUM(fit2.fit_amount)
FROM financial_transaction fit2
WHERE fit.fit_uid_pay_adj_rev_item = fit2.fit_uid_pay_adj_rev_item
AND fit2.dis_uid_discount <> 0)
ELSE 0
END) AS "GrossRevAmountwTax",
without having to requery the set yet again.
So, your issue with the PRFGrp.PSMCount is doing a similar thing. The alias PRFGrp was based on another table, column/condition and summation. The join has that available and SHOULD be visible to your query, not the "fit" alias as I originally had. So, please look at the alias references and final column names in case I missed something and hopefully this clarification makes more sense to you.
ADDITIONAL REVISIONS
The fields that have case/when that are not part of the group by expression are probably causing the failure as you should group by any and all non-aggregate columns in the returned set.
These include GrossRevAmountNoTax, NetRevenueAmount, and others... So, I just changed them to MAX() respectively. Since the group by all those other criteria including the low level ID columns would imply you don't get duplicates, so applying a MAX() to such should be the same value