我需要帮助来优化Oracle SQL查询以运行更长的时间

时间:2013-12-19 15:40:12

标签: sql oracle

@DRapp - 下面的修改后的查询:我需要帮助优化Oracle / SQL查询以运行超过2周的数据。它适用于2周的数据然后窒息。我继承了这个。所有业务规则都需要保留,但有没有一种方法可以简化这一点,以便它可以用于更大的数据集?具体的例子和提示将不胜感激。这可以分解为多个查询,但需要返回相同的结果。谢谢你的帮助。 Oracle SQL查询代码如下:

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)

2 个答案:

答案 0 :(得分:1)

如果您发现性能发生了阶段性变化(而不仅仅是相对于日期范围的查询持续时间的线性变化),则可能是由于以下三个问题之一:

  1. 查询优化的更改,您可以使用执行计划进行检查。 http://docs.oracle.com/cd/E11882_01/appdev.112/e25788/d_xplan.htm
  2. 数据量增加导致排序操作从最佳传递切换到一次传递,或从一次传递切换到多次传递,您可以使用v $ sql_workarea http://docs.oracle.com/cd/E11882_01/server.112/e40402/dynviews_3061.htm#REFRN30256
  3. 进行检查
  4. 数据“费率”的变化 - 例如,如果您从每天10,000条记录变为50,000条。
  5. 这将是我要检查的第一个问题。

答案 1 :(得分:1)

除了清理(格式化)查询以更好地了解正在发生的事情之外,我做了一些小改动。根据当前“适合”记录的内容,您有一些基于选择计数(*)或类似的列。从你的数据的声音,这是一些杀死系统。我已经将它们移动到三个单独的LEFT-JOIN到相应的表(Fit2Sum和FitGrace链接到FIT,PRFGrp通过psm别名链接)。

现在,那说,而且我不知道您的表的容量有多大,如果有任何可以限制的日期/时间字段,您可能想要设置一些限制(例如仅限一个月的数据.. )。但是,通过预先查询那些在每条记录上进行的操作,可能会对您的过程产生影响。

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 );

查询澄清......

帮助了解修订后的查询的内容。在几个字段中,您多次运行相同的查询,根据“当前”ID,即某些设施,人员等,得到COUNT(*)。如果您在字段级别执行该查询,则每行每行运行那些查询...

我所做的是对每个设施,人员,以及其他别名(例如Fit2Sum,FitGrace,PRFGrp)进行单个预聚合。在这些结果集中将相应的“ID”保持为分组,LEFT-JOIN根据该JOIN标准指向每个相应集合中的一条记录。

现在,案例/何时构建。由于已经执行了预聚合,并且连接是按照相应的“ID”列,因此您不再需要每列的COUNT(),只需从预聚合查询中获取最终列名称,测试一下。如果找到记录并且有记录,请执行与原始COUNT()相同的记录。在某些情况下,它会返回一个ID,其他的,返回0.所以,对于你的“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",

您正在根据fit_uid_pay_adj_rev_item选择fit_amount的sum()。由于我将此预先伪装成Fit2Sum别名,因此联接位于fit_uid_pay_adj_rev_item上,并且只是抓取该列(Fit2Sum.SumAmt),因此不必重复执行查询。

 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",

同样,由于它已经在Fit2Sum别名的记录中,它可以立即跟随

 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",

无需再次重新查询该集。

所以,PRFGrp.PSMCount的问题也在做类似的事情。别名PRFGrp基于另一个表,列/条件和求和。连接具有可用性,并且应该对您的查询可见,而不是像我最初那样的“适合”别名。因此,如果我错过了某些内容,请查看别名引用和最终列名称,并希望此澄清对您更有意义。

其他修订

具有大小写/不属于group by表达式的字段可能会导致失败,因为您应该按返回集合中的任何和所有非聚合列进行分组。

这些包括GrossRevAmountNoTax,NetRevenueAmount和其他......所以,我只是将它们分别更改为MAX()。由于所有其他标准的组(包括低级别ID列)都意味着您不会重复,因此对此应用MAX()应该是相同的值