SQL - 如果对应的值都相同,则使用值更新字段

Posted

技术标签:

【中文标题】SQL - 如果对应的值都相同,则使用值更新字段【英文标题】:SQL - update field with a value, if corresponding values are all the same 【发布时间】:2021-06-16 18:44:31 【问题描述】:

我手头有一个有趣的任务,我正试图弄清楚如何去做。

假设我的表格中有以下数据:

  Num1      Acct      Amt         Type1       Type2        AmtX     AmtY    AcctBadInd
  X12       111       90           X          1            NULL     NULL    NULL
  X12       222       -90          X          1            NULL     NULL    NULL
  X12       333       90           X          1            NULL     NULL    NULL

  Y33       111       75           Y          1            NULL     NULL    NULL
  Y33       444       -75          Y          1            NULL     NULL    NULL

  Z44       111       55           Y          1            NULL     NULL    NULL
  Z44       111       55           Y          0            NULL     NULL    NULL
  Z44       444       -65          Y          1            NULL     NULL    NULL

以下是几个示例。唯一需要注意的是,给定的 Num1 可以有任意数量的记录,但始终 >= 2。因此它可能是 2、3、4、5,并且相同的逻辑适用于所有情况。

    验证所有Type2=1 记录的ABS(AMT) 是否相同。如果所有 3 条记录都具有相同的 AMT,则该 Num1 为 SET AMTX=ABS(AMT)。或者,如果Type1 was Y for X12 - 那么我们将改为更新AmtY = ABS(AMT)

    Num1 = Y33 - 在这种情况下,我们再次要验证ABS(AMT)Type2=1 相同。如果它们相等,那么因为Type1=Y,我们将设置AmtY =75

    Num1=Z44 - 在这种情况下,再次验证Type2=1 的 ABS(AMT) 是否相同。如果不相等,则不要更新AmtY,而是设置AcctBadInd = 1

最终结果

Num1      Acct      Amt         Type1       Type2        AmtX     AmtY    AcctBadInd
  X12       111       90           X          1            90     NULL    NULL
  X12       222       -90          X          1            90     NULL    NULL
  X12       333       90           X          1            90     NULL    NULL

  Y33       111       75           Y          1            NULL     75    NULL
  Y33       444       -75          Y          1            NULL     75    NULL

  Z44       111       55           Y          1            NULL     NULL    1
  Z44       444       -65          Y          1            NULL     NULL    1
  Z44       111       55           Y          0            NULL     NULL    NULL

我正在为此苦苦挣扎,我不希望得到答案,但至少希望得到提示或任何帮助,以便我可以继续前进。更重要的是,如果这可以以我想象的方式实现,而无需编写上帝知道有多少代码。

【问题讨论】:

【参考方案1】:

如果我理解正确,您可以这样做:

with cte as (
select * , type2, max(abs(Amt)) minAmt, min(abs(Amt)) maxAmt, count(*) cnt 
from table 
group by Num1 , type2
);

update t1
set   AmtX = case when cnt> 1 and Type2=1 and t1.type1 = 'X' and minAmt = maxAmt then minAmt end
    , AmtY = case when cnt> 1 and Type2=1 and t1.type1 = 'Y' and minAmt = maxAmt then minAmt end
    , AcctBadInd = case when cnt> 1 and Type2=1 and minAmt <> maxAmt then 1 end
from table t1 
join cte on t1.Num1 = cte.Num1
and t1.type2 = cte.type2

【讨论】:

谢谢 - 好主意。我正在考虑取 SUM(ABS(AMT)) 然后除以 Count【参考方案2】:

使用窗口函数

with t as (
    select *,
    AmtXnew = case when min(ABS(AMT)) over(partition by Num1, Type2) = max(ABS(AMT)) over(partition by Num1, Type2) 
                     and Type2 = 1 and Type1 ='X' then ABS(AMT) 
                else NULL end,
    AmtYnew = case when min(ABS(AMT)) over(partition by Num1, Type2) = max(ABS(AMT)) over(partition by Num1, Type2) 
                     and Type2 = 1 and Type1 ='Y' then ABS(AMT) 
                else NULL end,
    AcctBadIndnew = case when min(ABS(AMT)) over(partition by Num1, Type2) <> max(ABS(AMT)) over(partition by Num1, Type2) 
                     and Type2 = 1 then 1 else NULL end
    from tbl
)
update t set AmtX = AmtXnew,AmtY = AmtYnew, AcctBadInd = AcctBadIndnew;

【讨论】:

以上是关于SQL - 如果对应的值都相同,则使用值更新字段的主要内容,如果未能解决你的问题,请参考以下文章

Mysql如果某个字段值存在则更新另一个字段的值为原值+100,命令应该如何写?

如果插入的值与唯一约束冲突,则 SQL 触发器在插入时更新字段

mvc+ef6多字段排序表达式怎么写

MYSQL怎么将表中的A字段值更新B字段值?求sql语句

执行一条sql语句update多条不同值的记录实现思路

Mysql如何更新字段值