If your actual logic has a lot more rules than this, you better write it in a procedural language like PL / SQL or T-SQL, because there is a possibility ... other applications can use this logic using .. let's say .. * get_tax_for_pay (i_pay) * or something like that.
But if thatβs all you need, then the below SQL should be good enough.
Tested in Oracle, because at the moment I do not have access to the SQL server. If you have any questions, post it in the comments. Notes at the end.
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
For calculation...
You are only interested in taxation of amounts in which a particular payment crosses a predetermined threshold for the tax scale. Example .. $ 1000 is not taxed in the 3k-5k tax group.
In cases where the amount crosses the threshold, you will charge a minimum of a) (max-min) at that threshold b) (minimum payment threshold) so. for a fee of $ 5500, you will only pay $ 1000 in a tax group of $ 1000-2000. for payment, if 1200, you pay only $ 200 in a tax scale of $ 1000-2000.
If you do not have minimum and maximum values ββin different columns, you can use the input / delay functions or self-join to get both of them on the same line as in my test table. If you do not have a maximum value for the last range, use the NVL or the corresponding function to assign a really large value to determine the range. (or code for zeros :))