Jas*_*son 8 sql t-sql sql-server
我需要从累积值计算一个百分比.要应用于每行中每个值的百分比率取决于从另一个表中获取的费率.百分比率计算需要以分层方式进行,因为税收可能会根据收入计算.
例如:工资= 1000
600*10%[首先按较低税率计算600美元]
400*30%[按较高税率计算的剩余金额]
所以,我一直试图让这个工作,但不能解决它.DBA离开了,所以它被移交给我.大多数SQL我都没问题,但我不知道如何处理这个问题,或者我应该在谷歌搜索的内容,所以道歉这是一个简单的搜索,请指导我到URL和我'我会尝试自己解决!
无论如何,下面是数据表(#v)格式的示例和范围表(#tiers)的示例,以及我到目前为止的方法.我需要一个新的列,按照我上面的解释,以正确的百分比级别计算'cval'.
希望有人可以帮助或指出我正确的方向!谢谢,J.
create table #v(
id nvarchar(50),
val money,
tid int
)
insert into #v values ('a',30,1)
insert into #v values ('b',50,1)
insert into #v values ('c',10,1)
insert into #v values ('d',30,1)
insert into #v values ('e',-80,1)
create table #tiers (
tid int,
threshold money,
amount money
)
insert into #tiers values (1,0,30)
insert into #tiers values (1,40,40)
insert into #tiers values (1,100,50)
select * from
(
select v1.id, v1.tid, v1.val,sum(v2.val) cval
from #v v1
inner join #v v2 on v1.id >= v2.id
group by v1.id, v1.val, v1.tid
) a
left join
(
select a.tid, a.id, a.threshold [lower], b.threshold [upper] from
(
select rank() over (order by threshold) as id, tid, threshold, amount from #tiers
) a
left join
(
select rank() over (order by threshold) as id, tid, threshold, amount from #tiers
) b on a.id = b.id-1
) b on (a.cval >= lower and a.cval < upper) or (a.cval >= lower and upper is null)
Run Code Online (Sandbox Code Playgroud)
如果你的实际逻辑有比这个更多的规则,你最好用PL/SQL或T-SQL这样的过程语言编写它,因为很有可能..其他应用程序可能想要使用这个逻辑使用..say .. *get_tax_for_pay(i_pay)*或类似的东西.
但如果这就是你所需要的,那么下面的SQL应该足够好了.
在Oracle中测试过,因为我目前无权访问SQL Server.如果您有任何问题,请在评论中发布.最后的笔记.
create table gross_pay(
pay number);
insert into gross_pay values (1523);
insert into gross_pay values (500);
insert into gross_pay values (5600);
insert into gross_pay values (3523);
commit;
create table tax_range(
min_pay number,
max_pay number,
tax_percent number);
insert into tax_range values (1000, 2000, 10);
insert into tax_range values (2000, 3000, 20);
insert into tax_range values (3000, 4000, 30);
insert into tax_range values (4000, 100000, 35);
commit;
SQL> select * from gross_pay;
PAY
----------
1523
500
5600
3523
SQL> select * from tax_range;
MIN_PAY MAX_PAY TAX_PERCENT
---------- ---------- -----------
1000 2000 10
2000 3000 20
3000 4000 30
4000 100000 35
select g.pay, t.min_pay, t.max_pay, t.tax_percent,
(g.pay-t.min_pay) diff, (t.max_pay-t.min_pay) diff2,
(case when g.pay > t.min_pay then
least((t.max_pay-t.min_pay),(g.pay-t.min_pay))
else 0
end) Taxable
from gross_pay g, tax_range t
order by pay, min_pay
SQL> /
PAY MIN_PAY MAX_PAY TAX_PERCENT DIFF DIFF2 TAXABLE
---------- ---------- ---------- ----------- ---------- ---------- ----------
500 1000 2000 10 -500 1000 0
500 2000 3000 20 -1500 1000 0
500 3000 4000 30 -2500 1000 0
500 4000 100000 35 -3500 96000 0
1523 1000 2000 10 523 1000 523
1523 2000 3000 20 -477 1000 0
1523 3000 4000 30 -1477 1000 0
1523 4000 100000 35 -2477 96000 0
3523 1000 2000 10 2523 1000 1000
3523 2000 3000 20 1523 1000 1000
3523 3000 4000 30 523 1000 523
PAY MIN_PAY MAX_PAY TAX_PERCENT DIFF DIFF2 TAXABLE
---------- ---------- ---------- ----------- ---------- ---------- ----------
3523 4000 100000 35 -477 96000 0
5600 1000 2000 10 4600 1000 1000
5600 2000 3000 20 3600 1000 1000
5600 3000 4000 30 2600 1000 1000
5600 4000 100000 35 1600 96000 1600
select pay, sum(tax) from (
select pay, min_pay, max_pay, tax_percent, Taxable,
(Taxable* tax_percent/100) tax from (
select g.pay, t.min_pay, t.max_pay, t.tax_percent,
(g.pay-t.min_pay) diff, (t.max_pay-t.min_pay) diff2,
(case when g.pay > t.min_pay then
least((t.max_pay-t.min_pay),(g.pay-t.min_pay))
else 0
end) Taxable
from gross_pay g, tax_range t
order by pay, min_pay
PAY SUM(TAX)
---------- ----------
1523 52.3
3523 456.9
500 0
5600 1160
Run Code Online (Sandbox Code Playgroud)
为了计算......
您只对特定工资超过税率范围的给定阈值的金额征税感兴趣.示例.. 1000美元不会在3k-5k税率范围内纳税.
如果金额超过阈值,您将在该阈值b)(最低支付阈值)中收取a)(最大 - 最小)的最小值.如果支付5500,您只需在1000-2000美元的税率范围内收取1000美元.如果是1200,你只需在1000-2000美元的税率范围内收取200美元.
如果您在不同的列中没有最小值和最大值,则可以使用超前/滞后函数或自联接将两者都放在与测试表中相同的行中.如果最后一个范围没有最大值,请使用NVL或相应的函数指定一个非常大的值来定义范围.(或空代码:))
假设 Tiers 表中的 Amount 列应该是税率,您可以执行以下操作:
With VData As
(
Select V1.id, V1.val, V1.tid, Sum(V2.val) As CVal
From #V As V1
Join #V As V2
On V2.id <= V1.id
Group By V1.id, V1.val, V1.tid
)
, Tiers As
(
Select T1.tid
, T1.Amount
, T1.threshold As MinThreshold
, Min(Coalesce(T2.threshold, 2147483647)) As MaxThreshold
From #tiers As T1
Left Join #tiers As T2
On T2.threshold > T1.threshold
Group By T1.tid, T1.Amount, T1.threshold
)
Select V.id, V.val, V.tid, V.CVal
, Sum(
Case
When CVal > T.MaxThreshold Then T.Amount / 100.00 * T.MaxThreshold
When CVal >= T.MinThreshold Then T.Amount / 100.00 * (V.CVal - T.MinThreshold)
End) As TotalTax
From VData As V
Join Tiers As T
On T.tid = V.tid
Group By V.id, V.val, V.tid, V.CVal
Run Code Online (Sandbox Code Playgroud)