首页 > 解决方案 > Oracle 中带有 Merge 语句的 CTE

问题描述

我正在尝试创建一个 CTE 以在 Oracle 的 Merge 语句中使用相同的语句,但是遇到错误,所以请看一下并帮助我,之前我们使用子查询而不是 CTE,但是为了提高查询的响应时间我正在尝试 CTE 所以请建议我另一种方法来提高查询的响应时间。很想知道 oracle 是否像我在下面的代码中那样支持 CTE 和 Merge 语句。

    With TRANS_HIST 
As 
(Select 
        NUMERO_DE_CUENTA,
        TRANS_DATETIME,
        Lag(TRANS_DATETIME, 1) 
        over 
         (
          ORDER BY NUMERO_DE_CUENTA,TRANS_DATETIME) lag_trans_datetime 
          FROM db_fraud_bpd.tbl_event_new_transaction_h
         ) 
MERGE 
INTO DB_FRAUD_BPD.TBL_RT_FEATURES_TEMP t1
USING 
(
SELECT 
        RTTEMP.ACCOUNT_NUMBER,
        RTTEMP.TRANS_DATETIME,
        CASE WHEN STDDEV(TRANS_HIST.TRANS_DATETIME - TRANS_HIST.lag_trans_datetime) = 0 THEN NULL 
             WHEN ROUND(( ( (RTTEMP.TRANS_DATETIME - Max(TRANS_HIST.TRANS_DATETIME)) - Avg(TRANS_HIST.TRANS_DATETIME - TRANS_HIST.lag_trans_datetime)) / STDDEV(TRANS_HIST.TRANS_DATETIME -TRANS_HIST.lag_trans_datetime)),3) >999999999999999 THEN 999999999999999 
             WHEN ROUND(( ( (RTTEMP.TRANS_DATETIME - Max(TRANS_HIST.TRANS_DATETIME)) - Avg(TRANS_HIST.TRANS_DATETIME - TRANS_HIST.lag_trans_datetime)) / STDDEV(TRANS_HIST.TRANS_DATETIME -TRANS_HIST.lag_trans_datetime)),3) <-99999999999999 THEN -99999999999999 
             ELSE ROUND(( ( (RTTEMP.TRANS_DATETIME - Max(TRANS_HIST.TRANS_DATETIME)) - Avg(TRANS_HIST.TRANS_DATETIME - TRANS_HIST.lag_trans_datetime)) / STDDEV(TRANS_HIST.TRANS_DATETIME -TRANS_HIST.lag_trans_datetime)),3) 
             END AS TIME_DELTA_ZSCORE_PAST_90_DAYS 
             FROM  TRANS_HIST
             right outer join 
                                 db_fraud_bpd.tbl_rt_features_temp RTTEMP 
                                 ON Cast(RTTEMP.account_number AS INTEGER) = Cast(TRANS_HIST.NUMERO_DE_CUENTA AS INTEGER) 
                            WHERE 
                            (
                            TRANS_HIST.TRANS_DATETIME      <   RTTEMP.TRANS_DATETIME 
                            AND TRANS_HIST.TRANS_DATETIME  >= (RTTEMP.TRANS_DATETIME-90)
                            ) 
                            or  TRANS_HIST.TRANS_DATETIME IS NULL 
                                 GROUP BY 
                                 RTTEMP.account_number,
                                 RTTEMP.TRANS_DATETIME
                            )TEMP 
                            ON (t1.TRANS_DATETIME=TEMP.TRANS_DATETIME AND t1.ACCOUNT_NUMBER=TEMP.ACCOUNT_NUMBER) 
                            WHEN MATCHED 
                            THEN UPDATE 
                            SET t1.TIME_DELTA_ZSCORE_PAST_90_DAYS = TEMP.TIME_DELTA_ZSCORE_PAST_90_DAYS

标签: oracle

解决方案


可以CTE在语句中使用merge,但在合并子查询中的正确位置。

请参阅下面的示例

merge into tab
  using (with t as (
               select 1 id, 'x' x from dual union all
               select 2 id, 'y' x from dual)
        select * from t) b
  on (tab.id = b.id)
 when matched then
   update set tab.x = b.x
 when not matched then
  insert (id, x)
  values (b.id, b.x);

推荐阅读