【问题标题】:Is there a way to include CASE WHEN or NVL in MERGE oracle sql?有没有办法在 MERGE oracle sql 中包含 CASE WHEN 或 NVL?
【发布时间】:2020-09-03 08:09:58
【问题描述】:

我在下面有一个合并语句,我想添加一个条件,即如果 X_RECEIVED_ON_DT 为空,它将使用 FULFILLED_ON_DT 和 PO_CLOSED_DT 中的日期,它们是 TGT(目标表)中的列来填充 TGT.X_GAAP_EXCH_RATE_WID 列

 MERGE
/*+ PARALLEL(8) */
INTO W_PURCH_COST_F TGT USING
(SELECT
  /*+ PARALLEL(8) */
  cost.INTEGRATION_ID,
  cost.X_RECEIVED_ON_DT,
  cost.LOC_CURR_CODE,
  COALESCE(gaap.ROW_WID,0) X_GAAP_EXCH_RATE_WID
FROM W_Purch_Cost_F_3955 cost
JOIN W_DAY_D wday
ON TRUNC(cost.X_RECEIVED_ON_DT)=TRUNC(wday.CALENDAR_DATE)
LEFT OUTER JOIN WC_GAAP_EXCH_RATE_G gaap
ON gaap.PERIOD               =wday.PER_NAME_ENT_PERIOD
AND cost.LOC_CURR_CODE       =gaap.FROM_CURCY_CD
) SRC ON (TGT.INTEGRATION_ID = SRC.INTEGRATION_ID AND TGT.DATASOURCE_NUM_ID = 310)
WHEN MATCHED THEN
  UPDATE SET TGT.X_GAAP_EXCH_RATE_WID = SRC.X_GAAP_EXCH_RATE_WID;

【问题讨论】:

    标签: sql oracle merge nvl


    【解决方案1】:

    如果您想在source 查询中引用W_PURCH_COST_F(别名TGT),则必须将其包含在SRCFROM 子句中。 p>

    这意味着您在此 MERGE 语句中有两个 W_PURCH_COST_F 表 - 一个作为合并目标(正如您现在已经拥有的那样),另一个作为“源”用于将其与其他表连接起来在SRC。那么使用NVLCASEDECODE 并做你想做的事就是一个简单的任务。

    不过,我不太明白你将如何同时使用FULFILLED_ON_DTPO_CLOSED_DT,但我希望你知道。


    基于 Scott 架构的示例(因为我没有您的表):

    这行不通 - 你不能在 SRC 中引用 TGT

    SQL> merge into emp e
      2  using (select distinct d.deptno, d.dname, d.loc
      3         from dept d
      4         where d.deptno = e.deptno                --> not allowed
      5        ) x
      6  on (e.deptno = x.deptno)
      7  when matched then update set e.ename = x.loc;
           where d.deptno = e.deptno
                            *
    ERROR at line 4:
    ORA-00904: "E"."DEPTNO": invalid identifier
    

    但是,如果在SRCFROM 子句中使用,它有效

    SQL> merge into emp e
      2  using (select distinct d.deptno, d.dname, d.loc
      3         from dept d join emp a on a.deptno = d.deptno
      4        ) x
      5  on (e.deptno = x.deptno)
      6  when matched then update set e.ename = x.loc;
    
    14 rows merged.
    
    SQL>
    

    您可能要考虑的选项是:

    • 嵌套NVL:nvl(x_received_on_dt, nvl(fulfilled_on_dt, po_closed_dt))

    • coalesce(返回第一个非空值):

      coalesce(x_received_on_dt, fulfilled_on_dt, po_closed_dt, sysdate) 
      

    coalesce 对我来说似乎是一个更好的选择。

    【讨论】:

    • 嗨@Littlefoot,对不起,它将使用 FULFILLED_ON_DT 或 PO_CLOSED_DT,如果 FULFILLED_ON_DT 不为空,它将使用它,如果其为空,将使用 PO_CLOSED_DT,否则为 0
    • 好的,使用嵌套的 NVL。但是,由于数据类型不一致,您不能将 0(数字)与 DATE 值一起使用。应该是其他值 - DATE 值(例如 SYSDATE 或某些 无效 日期,例如 DATE '1000-01-01')。
    • 嗨@Littlefoot,我收到了缺少关键字的错误。这是我的选择 NVL(CASE WHEN cost.X_RECEIVED_ON_DT IS NULL THEN SRC1.FULFILLED_ON_DT ELSE SRC1.PO_CLOSED_DT,0)
    • 我编辑了我的答案并添加了 NVL 和 COALESCE 示例;看看吧。
    猜你喜欢
    • 2021-09-15
    • 2020-07-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-11-13
    • 2012-09-20
    相关资源
    最近更新 更多