更新以前的记录

时间:2014-06-03 10:29:48

标签: sql-server

请注意我有两张桌子:

我希望表薪水中的trnamt更新到rec记录中的tbl_emi,但金额不应超过每条记录的emi金额,例如在这种情况下,应添加工资表中的金额2000 1000到第一个记录,另一个1000到第二个记录到tbl_emi表

               tbl_emi
EMI      DUEDT      REC     Acno
1000    4/30/2014   0       123
1000    5/30/2014   0       123 
1000    6/30/2014   0       123 

                  slary

             Acno      Trnamt
             123         2000

3 个答案:

答案 0 :(得分:1)

您可以通过加入acno上的表格并使用其他表格rec更新trnamt来尝试此类内容。在case语句中,它会检查trnamt > emi是否只会分配一半,否则将分配完整

UPDATE
    im
SET
    rec = CASE WHEN gm.trnamt > im.emi THEN (gm.trnamt - im.emi)
          ELSE gm.trnamt END 
FROM
    tbl_emi im
    JOIN
    salary gm ON im.acno=gm.acno 

答案 1 :(得分:1)

这个脚本应该适用于所有情况,即使在较大的数据集上也应该非常有效。您可以查询中间临时表以查看我正在做什么。每行的表#accumulated_amount_with_salary具有计算分配金额所需的所有数据。

编辑:因为我假设REC在开头总是0,我的查询无法正常工作。我通过重新计算EMI(减去REC数量)

来更新查询
--drop table #accumulated_amount;
select a.emi-a.rec as emi, a.duedt, a.rec, a.acno, coalesce(sum(b.emi-b.rec),0) as emi_accumulated
into #accumulated_amount
from tbl_emi a
    left join tbl_emi b on a.acno = b.acno and b.duedt < a.duedt
group by a.emi, a.duedt, a.rec, a.acno;

--drop table #accumulated_amount_with_salary;
select a.*, s.trnamt as salary_amt
into #accumulated_amount_with_salary
from #accumulated_amount a
    inner join slary s on a.acno = s.acno;

update #accumulated_amount_with_salary
set rec = rec + case
    when salary_amt < emi_accumulated then 0
    when (salary_amt - emi_accumulated) < emi then salary_amt - emi_accumulated
    else emi
end

update t
set rec = a.rec
from tbl_emi t
    inner join #accumulated_amount_with_salary a on t.acno = a.acno and t.duedt = a.duedt;

答案 2 :(得分:1)

每行的AcNo + DUEDT都是唯一的吗?否则你需要一些关键的

WITH RowRanges As (
    SELECT DUEDT
          ,AcNo
          ,SUM(EMI) OVER (PARTITION BY AcNo ORDER BY DUEDT ROWS UNBOUNDED PRECEDING) - EMI AS MinValue
          ,SUM(EMI) OVER (PARTITION BY AcNo ORDER BY DUEDT ROWS UNBOUNDED PRECEDING) AS MaxValue
    FROM tbl_emi
)
UPDATE tbl_emi
SET REC = CASE WHEN Trnamt < MaxValue THEN TrnAmt - MinValue
               ELSE MaxValue - MinValue
          END
FROM tbl_emi 
     INNER JOIN RowRanges
         ON RowRanges.DUEDT = tbl_emi.DUEDT
            AND RowRanges.AcNo = tbl_emi.AcNo
     INNER JOIN slary
         ON slary.AcNo = RowRanges.AcNo
WHERE RowRanges.MinValue < slary.Trnamt