【问题标题】:How to Update to SET Table1.ColumnX = Table2.ColumnX with a where clause如何使用 where 子句更新为 SET Table1.ColumnX = Table2.ColumnX
【发布时间】:2020-04-02 20:42:50
【问题描述】:

假设我有一张名为 InsuranceMember 的表,其中包含保险计划的所有成员及其配偶。但是哦不!对于 CountryCD 为“Canada”且 PlanCD 为“99999”的配偶,此表中的 MemberNum(主键)均不正确!

但幸运的是,有一个名为 InsurancePlan 的表,其中包含配偶,并且这些配偶的 MemberNum(也是主键)都是正确的!

所以在这个假设中,我需要一个条件更新语句来设置 InsuranceMember.MemberNum = InsurancePlan.MemberNum where CountryCD = 'Canada' and PlanCD = '99999'

我如何编写查询来完成这项工作并更新每一行。

当我尝试编写此查询时,我总是会收到此错误: -811 UPDATE 语句的 set 子句中嵌入的 SELECT 语句或子选择的结果是一个多行的表,或者基本谓词的子查询的结果是多于一个值

这对作为 SQL 初学者的我来说非常困惑,但我确信我所描述的情况很多人都处理过。

编辑:这是我使用的生成该更新的代码示例:

UPDATE PRD.InsuranceMember mem
set mem.MemberNum = ( Select pln.MemberNum
                   from PRD.InsurancePlan pln
                   where mem.MemberNum <> pln.MemberNum
                   and   mem.MoneySource = pln.MoneySource
                     )

WHERE mem.MemberNum = (SELECT pln2.MemberNum FROM PRD.InsurancePlan pln2
                     WHERE mem.ClientCd = pln2.ClientCd
                       AND mem.PLanCd = pln2.PlanCd)
AND Mem.MoneySource='3' 
AND Mem.CountryCd = 'Canada'
AND Mem.PlanCd = '99999'        
;

【问题讨论】:

  • 请贴出产生错误信息的代码。
  • 标记时要小心。 DB2 sql 服务器。
  • 我相信您需要一个比 CountryCD 和 PlanCD 更严格的密钥。有了这个加入,不幸的是,更新将不起作用,因为 insurancePlan 中所有加拿大和 PlanCD 99999 的行将匹配 InsuranceMember 中的所有加拿大和 PlanCD 99999 行
  • 您能否为您问题中的每个表格发布一个简化的CREATE TABLE 声明?
  • 下面是产生该错误的代码示例:

标签: sql db2 updates ibm-data-studio


【解决方案1】:

尝试在每个子查询的末尾添加FETCH FIRST ROW ONLY,这将通知数据库这些表达式不会返回多个值。

UPDATE PRD.InsuranceMember mem
SET mem.MemberNum = ( SELECT pln.MemberNum
               FROM PRD.InsurancePlan pln
               WHERE mem.MemberNum <> pln.MemberNum
               AND   mem.MoneySource = pln.MoneySource
               FETCH FIRST ROW ONLY
                 )
WHERE mem.MemberNum = (SELECT pln2.MemberNum 
               FROM PRD.InsurancePlan pln2
               WHERE mem.ClientCd = pln2.ClientCd
               AND mem.PLanCd = pln2.PlanCd
               FETCH FIRST ROW ONLY
                 )
AND mem.MoneySource='3' 
AND mem.CountryCd = 'Canada'
AND mem.PlanCd = '99999'        
;

【讨论】:

    【解决方案2】:

    在这种情况下使用 SELECT 的 UPDATE 会有所帮助,因为您可以只运行 SELECT 部分并确保 newMemberNum 子选择只返回一行

    UPDATE (
        SELECT
            MemberNum
        ,   MoneySource
        ,   CountryCd
        ,   PlanCd
        ,   ( Select pln.MemberNum
               from PRD.InsurancePlan pln
               where mem.MemberNum <> pln.MemberNum
               and   mem.MoneySource = pln.MoneySource
             ) AS NewMemberNum
        FROM
            PRD.InsuranceMember mem
        )
    SET MemberNum = NewMemberNum
    WHERE
        MoneySource='3' 
    AND CountryCd = 'Canada'
    AND PlanCd = '99999'        
    AND MemberNum IS DISTINCT FROM NewMemberNum
    

    因此,您可能需要在子选择中使用 MAX(pln.MemberNum) 或 DISTINCT,以确保在 PRD.InsuranceMember 中为每个选定行最多找到一行

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-02-07
      • 2014-12-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多