基于Multi-Join GroupBy SubQuery的更新表

Sco*_*man 4 sql oracle

我有以下针对Oracle数据库编写的Select:

SELECT d.REGION_NAME REGION, 'SM' PLAN, b.TRADING_CODE ACCOUNT, c.RM_SM_NAME SM_NAME,'Q116' TIMEPERIOD,
  SUM(CASE WHEN a.PAYOUT_TYPE = 'BONUS' THEN a.PAYOUT END) as BONUS,
  SUM(CASE WHEN a.PAYOUT_TYPE = 'MAINTENANCE' THEN a.PAYOUT END) as MAINTENANCE
FROM FACT_COMM_LARGE_ACCT_BONUS a
INNER JOIN DIM_TRADING_ACCOUNTS b on b.trading_dwkey = a.trading_dwkey
INNER JOIN REF_RM_SM_REGION c on c.RM_SM_USER_CODE = a.RM_SM_USER_CODE
INNER JOIN REF_REGION d on d.REGION_DWKEY = c.REGION_DWKEY
GROUP BY d.REGION_NAME, 'SM', b.TRADING_CODE, c.RM_SM_NAME;
Run Code Online (Sandbox Code Playgroud)

我想对这些数据的结果是更新另一个表中的BONUS和MAINTENANCE字段,其中ACCOUNT的组合 SM_NAME | TIMEPERIOD是平等的.

我一直在玩Update语句,但是我遇到了困难.我尝试以两种不同的方式使用SubQuery和WHERE子句加入.

方式1

UPDATE WORK_COMMISSION_SUMMARY_FINAL e
    SET e.BONUS = (SELECT subqry1.BONUS FROM (
            SELECT d.REGION_NAME REGION, 'SM' PLAN, b.TRADING_CODE ACCOUNT, c.RM_SM_NAME SM_NAME,'Q116' TIMEPERIOD,
                SUM(CASE WHEN a.PAYOUT_TYPE = 'BONUS' THEN a.PAYOUT END) as BONUS,
                SUM(CASE WHEN a.PAYOUT_TYPE = 'MAINTENANCE' THEN a.PAYOUT END) as MAINTENANCE
            FROM FACT_COMM_LARGE_ACCT_BONUS a
            INNER JOIN DIM_TRADING_ACCOUNTS b on b.trading_dwkey = a.trading_dwkey
            INNER JOIN REF_RM_SM_REGION c on c.RM_SM_USER_CODE = a.RM_SM_USER_CODE
            INNER JOIN REF_REGION d on d.REGION_DWKEY = c.REGION_DWKEY
            GROUP BY d.REGION_NAME, 'SM', b.TRADING_CODE, c.RM_SM_NAME) AS subqry1
          WHERE subqry1.ACCOUNT = e.Account and subqry1.SM_NAME = e.SM_NAME and subqry1.TIMEPERIOD = e.TIMEPERIOD);
Run Code Online (Sandbox Code Playgroud)

方式2

UPDATE WORK_COMMISSION_SUMMARY_FINAL e
    SET e.BONUS = subqry1.BONUS,
        e.MAINTENANCE = subqry1.MAINTENANCE
    (SELECT d.REGION_NAME REGION, 'SM' PLAN, b.TRADING_CODE ACCOUNT, c.RM_SM_NAME SM_NAME,'Q116' TIMEPERIOD,
      SUM(CASE WHEN a.PAYOUT_TYPE = 'BONUS' THEN a.PAYOUT END) as BONUS,
      SUM(CASE WHEN a.PAYOUT_TYPE = 'MAINTENANCE' THEN a.PAYOUT END) as MAINTENANCE
    FROM FACT_COMM_LARGE_ACCT_BONUS a
    INNER JOIN DIM_TRADING_ACCOUNTS b on b.trading_dwkey = a.trading_dwkey
    INNER JOIN REF_RM_SM_REGION c on c.RM_SM_USER_CODE = a.RM_SM_USER_CODE
    INNER JOIN REF_REGION d on d.REGION_DWKEY = c.REGION_DWKEY
    GROUP BY d.REGION_NAME, 'SM', b.TRADING_CODE, c.RM_SM_NAME) as subqry1
  WHERE subqry1.ACCOUNT = e.ACCOUNT and subqry1.SM_NAME = e.SM_NAME and subqry1.TIMEPERIOD = e.TIMEPERIOD;  
Run Code Online (Sandbox Code Playgroud)

我对更高级的SQL东西很陌生,而且非常困在这里.我可能过于复杂,我试图解决它,但如果有人可以伸出援助之手,我会很感激.

最后要注意的是,这很可能是更大程序的一部分,所以如果我需要分步,这是一个可能的解决方案.

mat*_*guy 8

使用MERGE语句,这样的更新通常更容易编写,读取和维护.Oracle文档:https://docs.oracle.com/cd/B28359_01/server.111/b28286/statements_9016.htm

merge into work_commission_summary_final e
   using [**your subquery here**]        subqry1
   on (     subqry1.account    = e.account
        and subqry1.sm_name    = e.sm_name
        and subqry1.timeperiod = e.timeperiod
   )
when matched
   then update e.bonus       = subqry1.bonus,
               e.maintenance = subqry1.maintenance;
Run Code Online (Sandbox Code Playgroud)