【问题标题】:Oracle SQL Merge Statement with Conditions带条件的 Oracle SQL 合并语句
【发布时间】:2020-07-07 15:32:37
【问题描述】:

我对 SQL 比较陌生,并且遇到了目标表未更新的问题。 我在相关列中有重复的帐户#(键)和不同的联系信息。我正在尝试将联系信息(源)合并到单行/帐号中,不重复的联系信息进入(目标)扩展列。

我构造了一个带有 case 条件的 Merge 语句来检查数据是否存在于目标表中。如果数据不在目标表中,则在扩展列中添加信息。问题是目标表没有更新。源表和目标表都定义了相似性。

**Merge SQL- reduced query**
MERGE INTO target tgt
    USING (select accountno, cell, site, contact, email1 from (select w.accountno, w.cell, w.site, w.contact, email1, row_number() over (PARTITION BY w.accountno order by accountno desc) acct 
    from source w) inn where inn.acct =1) src 
    ON (tgt.accountno = src.accountno)
WHEN MATCHED
    THEN 
        UPDATE SET
                  tgt.phone4 =  
                  CASE WHEN src.cell <> tgt.cell
                  THEN src.cell
                  END,
                  tgt.phone5 =
                  CASE WHEN src.site <> tgt.site
                  THEN src.site
                  END

我已验证源表中存在应添加到目标表中的 accountno 的联系信息。我非常感谢任何关于为什么没有更新目标表的见解。 我在 Stack 上看到了类似的问题,但没有得到回复。

【问题讨论】:

    标签: sql oracle merge case


    【解决方案1】:

    您在 using 子句中的 SRC 子查询为每个 accountno 仅返回 1 个随机行。 您需要聚合它们,例如使用 PIVOT:

    with source(accountno, cell, site, contact) as ( --test data:
       select 1,8881234567,8881235678,8881236789 from dual union all
       select 1,8881234567,8881235678,8881236789 from dual
    )
    select accountno, contact, 
           r1_cell, r1_site, 
           r2_cell, r2_site
    from (select s.*,row_number()over(partition by accountno order by cell) rn
          from source s
         )
    pivot (
       max(cell) cell,max(site) site
        FOR rn
        IN (1 R1,2 R2)
    )
    

    所以最后你可以将 r1_cell、r1_site、r2_cell、r2_site 与目标值进行比较并使用所需的值:

    MERGE INTO target tgt
        USING (
                select accountno, contact, 
                       r1_cell, r1_site, 
                       r2_cell, r2_site
                from (select s.*,row_number()over(partition by accountno order by cell) rn
                      from source s
                     )
                pivot (
                   max(cell) cell,max(site) site
                    FOR rn
                    IN (1 R1,2 R2)
                )
              ) src 
        ON (tgt.accountno = src.accountno)
    WHEN MATCHED
        THEN 
            UPDATE SET
                      tgt.phone4 =  
                      CASE 
                           WHEN src.r1_cell <> tgt.cell 
                              THEN src.r1_cell
                              ELSE src.r2_cell
                      END,
                      tgt.phone5 =
                      CASE WHEN src.r1_site <> tgt.site 
                         THEN src.r1_site
                         ELSE src.r2_site
                      END
    /
    

    【讨论】:

      【解决方案2】:

      问题在于您在 row_numbering 具有相同 account_number 的行中使用的逻辑。

      MERGE 
       INTO target tgt
      USING (select accountno, cell, site, contact, email1 
               from (select w.accountno, w.cell, w.site, w.contact, email1
                          , row_number() over (PARTITION BY w.accountno order by w.accountno desc) acct 
                      from source w
                    left join target w2
                        on w.accountno=w2.accountno
                     where w2.cell is null /* get records which are not in target*/ 
                    ) inn 
               where inn.acct =1
             ) src 
         ON (tgt.accountno = src.accountno)
      WHEN MATCHED THEN 
           UPDATE 
              SET tgt.phone4 = src.cell,
                  tgt.phone5 = src.site
      

      【讨论】:

      • 感谢您的解释,尽管我需要一些时间来理解解释,以便我可以使用它来满足我的全部要求。我必须修改您提供的更新代码以使用源表信息更新目标表并检查 tgt.phone4 是否为空,因为 tgt.cell 几乎从不为空。非常感谢您的帮助。
      • 我刚刚意识到我错误地使用别名 tgt 进行更新。正确的方法是 tgt.phone4 = src.cell,tgt.phone5 = src.site
      • np,我在测试时注意到了。我的问题的要点是我不能确保我正在比较的目标行和源行是相同的。我还注意到,无论目标表中是否已经存在 src 数据,目标表都会更新。如果我在 SET 中尝试使用 case 子句,则不会更新任何数据。谢谢你让我走上正确的道路。
      猜你喜欢
      • 2020-07-05
      • 2013-05-11
      • 1970-01-01
      • 1970-01-01
      • 2018-08-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-03-27
      相关资源
      最近更新 更多