How do I write a sql statement to calculate totals, based on groups from another table?

I need to calculate a percentage from a cumulative value. The percent rate to be applied to each value in each row is dependent on rates taken from another table. The percent rate calculation needs to happen in a tiered fashion, as tax might be calculated on earnings.

eg: Wages = 1000
600 * 10% [First $600 calculated at lower tax rate]
400 * 30% [Remaining amount calculated at higher tax rate]

So, I've been trying to get this to work, but can't sort it out. The DBA is away so it's been handed over to me. Most SQL I'm ok with, but I am not sure how to approach this issue, or what I should be searching for in google either, so apologies is this is a simple search away, please just direct me to the URL and I'll try and work it out myself!

Anyway, below is an example of the format of the data table (#v) and an example of the ranges table (#tiers), and how I have got on so far. I need a new column which has the calculation of 'cval' at the correct percent rate tiers as I've explained above.

Hope someone can help or point me in the right direction! Thanks, 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)
8
задан Jason 6 May 2011 в 16:42
поделиться