SQL 服务器中 DML UPDATE/INSERT 触发器的累积分层速率计算?
Cumulative tiered rate calculation in SQL Server for DML UPDATE/INSERT trigger?
本质上,使用 SQL 服务器,我想从下面的当前 table 中获取“总金额”(它是从 INSERT
或 UPDATE
) 然后让“总金额”运行 通过“分层 Table” 导出所需输出中的“总 A $” table.
我想这可能需要用触发器(也许是函数?)来完成,因为这个计算会发生在 INSERT
或 UPDATE
上,并且因为条件逻辑可以合并到其中因为有不同的等级 table 具有不同的 Min/Max 值和不同等级的百分比阈值。
下面的例子当然是累加的,和边际所得税率一样,前10000是90%(Total A),第二层计算19999是60%,第三层69999是40%,等等等等。还有其他不同等级的地区,只是简单的查找参考值。
分层table:
RegionID | TierNo | Min | Max | Total A | Total B |
---|---|---|---|---|---|
3 | 1 | 0 | 10000 | .90 | .10 |
3 | 2 | 10001 | 30000 | .60 | .40 |
3 | 3 | 30001 | 100000 | .40 | .60 |
3 | 4 | 100001 | 500000 | .40 | .60 |
3 | 5 | 500001 | 999999999999 | .20 | .80 |
当前table样本:
TransID | RegionID | GrossAmt | Total A % | Total A $ | Net Amt |
---|---|---|---|---|---|
100001 | 3 | 125000 |
期望的输出:
TransID | RegionID | GrossAmt | Total A % | Total A $ | Net Amt |
---|---|---|---|---|---|
100001 | 3 | 125000 | 0.47 | 59000 | 66000 |
任何想法或指导都将非常有帮助和感激。
首先,你的等级不太对。例如,第一个从 0
开始并在 10000
结束,但下一个从 10001
开始,留下 10000
和 10001
之间的任何内容下落不明.相反,让您的层彼此相邻,并使用 > AND <=
.
其次,这根本不需要触发器。您应该在需要时即时计算它。如果需要,创建视图或内联 Table 值函数。
它看起来像是一个相当简单的分组联接,您可以使用 CROSS APPLY
巧妙地完成它。您只需要计算每层乘以多少:GrossAmt
或 Max
中的较低者,减去 Min
SELECT
c.*,
[Total A %] = t.Total / c.GrossAmt,
[Total A $] = t.Total,
[Net Amt] = c.GrossAmt - t.Total
FROM CurrentData c
CROSS APPLY (
SELECT
Total = SUM((v.ActualMax - t.Min) * t.[Total A])
FROM Tiers t
CROSS APPLY (VALUES(
CASE WHEN c.GrossAmt < t.Max THEN c.GrossAmt ELSE t.Max END
)) v(ActualMax)
WHERE c.GrossAmt > t.Min
) t;
如果需要,您可以将其作为内联 Table 值函数来执行。
CREATE FUNCTION dbo.GetTieredTotal (@GrossAmt decimal(18,9))
RETURNS TABLE
AS RETURN
SELECT
Total = SUM((CASE WHEN @GrossAmt < t.Max THEN @GrossAmt ELSE t.Max END - t.Min) * t.[Total A])
FROM Tiers t
WHERE @GrossAmt > t.Min
;
然后您可以将主查询更改为
SELECT
c.*,
[Total A %] = t.Total / c.GrossAmt,
[Total A $] = t.Total,
[Net Amt] = c.GrossAmt - t.Total
FROM CurrentData c
CROSS APPLY dbo.GetTieredTotal (c.GrossAmt) t;