在基于等级的税制上计算税的情况

时间:2019-01-31 07:58:02

标签: sql-server tsql case aggregate-functions

我有一个包含用户收入的表,我希望根据该收入计算他们的所得税百分比。问题在于每个支架的税率都不相同,例如:

MinLimit| MaxLimit| TaxRate
0       | 14000   | 10.50
14001   | 48000   | 17.50
48001   | 70000   | 30.00
70001   | 1000000 | 33.00

因此,如果1个人的收入为49,000,则应按以下方式征税:

14000 * 0.1050 = 1470
34000 * 0.1750 = 5950 (34,000 is income between 14k -48k)
1000  * 0.30   = 300  (1000 is remaining income)
total = 1470 + 5950 + 300 = 7720

我正在SQL Server 2017 Express上运行。我尝试运行链式CASE-WHEN语句,即

CASE WHEN
     THEN

     WHEN
     THEN 
and so on...

但是我可以弄清楚如何增加减去余数的逻辑。请在下面找到我的代码。

SELECT 'emp_name' AS 'Director', 
SUM(ABS([Transaction Amount])) AS 'INCOME',
CASE WHEN (SUM(ABS([Transaction Amount])) < 14000)
     THEN ((SUM(ABS([Transaction Amount])) - 14000) * 0.1050)

     WHEN (SUM(ABS([Transaction Amount])) > 14000 and (SUM(ABS([Transaction Amount])) < 48001))
     THEN (((SUM(ABS([Transaction Amount])) - 14000) * 0.1050) - 48000) * 0.1750 end AS 'Income Tax'
FROM Transactions

编辑1: 输入数据:

Transaction Type| PAYEE  | Transaction Amount
DEBIT           | DEBIT  | -184.00
CREDIT          | CREDIT | 4000.00
...

输出数据:

Director | INCOME  | Income Tax
emp_name | 45100.00| NULL

请让我知道我要去哪里或者我的想法有误。

3 个答案:

答案 0 :(得分:1)

关联子查询可能是最容易阅读和理解的

form_tag

当您意识到您需要做的与实际收入相关的唯一数学与实际适用的括号相关时,它得到了显着简化-隐含地使用了所有较低利率的括号,因此您可以仅从费率表中计算出其他税额。

我已经稍微更改了费率数据,以使计算变得简单明了,并且不需要进行许多declare @t table (MinLimitExclusive int, MaxLimitInclusive int, TaxRate decimal(5,2)) insert into @t(MinLimitExclusive,MaxLimitInclusive,TaxRate) values (0 ,14000 , 10.50), (14000,48000 , 17.50), (48000,70000 , 30.00), (70000,1000000, 33.00) declare @transactions table (Income decimal(10,2)) insert into @transactions (Income) values (49000) select (Income - MinLimitExclusive) * TaxRate / 100 + (select SUM((rates2.MaxLimitInclusive - rates2.MinLimitExclusive) * rates2.TaxRate / 100) from @t rates2 where rates2.MaxLimitInclusive <= rates.MinLimitExclusive) from @transactions tr inner join @t rates on tr.Income > rates.MinLimitExclusive and tr.Income <= rates.MaxLimitInclusive 调整。

答案 1 :(得分:1)

我建议您以1而不是0的MinLimit开始。其余的计算很简单:

declare @taxslabs table (minlimit int, maxlimit int, taxrate decimal(18, 2));
insert into @taxslabs values
(1,     14000,   10.50),
(14001, 48000,   17.50),
(48001, 70000,   30.00),
(70001, 1000000, 33.00);

select persons.*, taxslabs.*, taxableamount, taxableamount * taxrate / 100 as taxamount
from (values
    (1, 49000),
    (2, 70000),
    (3, 70001)
) as persons(id, income)
cross join @taxslabs as taxslabs
cross apply (select case when income <= maxlimit then income else maxlimit end - minlimit + 1) as ca(taxableamount)
where minlimit <= income

您可以将此查询放在子查询中,然后使用GROUP BY ... SUM()SUM() OVER (PARTITION BY)计算税金总和。

示例输出:

| id | income | minlimit | maxlimit | taxrate | taxableamount | taxamount        |
|----|--------|----------|----------|---------|---------------|------------------|
| 1  | 49000  | 1        | 14000    | 10.50   | 14000         | 1470.000000      |
| 1  | 49000  | 14001    | 48000    | 17.50   | 34000         | 5950.000000      |
| 1  | 49000  | 48001    | 70000    | 30.00   | 1000          | 300.000000       |
| 2  | 70000  | 1        | 14000    | 10.50   | 14000         | 1470.000000      |
| 2  | 70000  | 14001    | 48000    | 17.50   | 34000         | 5950.000000      |
| 2  | 70000  | 48001    | 70000    | 30.00   | 22000         | 6600.000000      |
| 3  | 70001  | 1        | 14000    | 10.50   | 14000         | 1470.000000      |
| 3  | 70001  | 14001    | 48000    | 17.50   | 34000         | 5950.000000      |
| 3  | 70001  | 48001    | 70000    | 30.00   | 22000         | 6600.000000      |
| 3  | 70001  | 70001    | 1000000  | 33.00   | 1             | 0.330000         |

答案 2 :(得分:0)

我认为在事务表上使用group by并加入到费率计税表的此相关查询可能会导致除外结果

CREATE TABLE #Transaction  
(
    tID             int PRIMARY KEY,  
    tIdUser         varchar(50),
    Amount          decimal(9,3)
 );  
CREATE TABLE #RefTaxe  
(
    pID             int PRIMARY KEY, 
    minLimit        int, 
    maxLImit        int,
    rate            decimal(9,3)
); 




INSERT INTO #Transaction 
SELECT 1, 'User1', 1259.3
UNION
SELECT 2, 'User1', 10259.3
UNION
SELECT 3, 'User3', 30581.3
UNION 
SELECT 4, 'User2', 75000.36
UNION 
SELECT 5, 'User2', 15000.36
UNION 
SELECT 6, 'User4', 45000.36
UNION 
SELECT 7, 'User4', 5000.36


INSERT INTO #RefTaxe 
select 1,0,14000,10.50
UNION
SELECT 2,14001,48000,17.50
UNION
SELECT 3,48001,70000,30.00
UNION
SELECT 4,70001,1000000,33.00


-- SELECT * FROM #Transaction

-- SELECT * FROM #RefTaxe

--  SELECT tIdUser,SUM(AMOUNT) as SumAmount, CAST(FLOOR(SUM(AMOUNT))as int) as SumAsInt     FROM #Transaction GROUP BY tIdUser
/***/
-- Perform select 
/***/
SELECT tIdUser, SumAmount as 'DetaxedAmount' ,SumAmount * (rate/100) as TaxOfAmount, SumAmount+ SumAmount * (rate/100) as TaxedAmount
FROM #RefTaxe RT    
JOIN (
    SELECT tIdUser,SUM(AMOUNT) as SumAmount,  CAST(FLOOR(SUM(AMOUNT))as int) as SumAsInt
    FROM #Transaction GROUP BY tIdUser
)   AS GroupedTR ON RT.minLimit <= SumAsInt AND RT.maxLImit >= SumAsInt


/***/

DROP TABLE #Transaction
DROP TABLE #RefTaxe

结果输出:

tIdUser DetaxedAmount   TaxOfAmount     TaxedAmount
User1   11518.600     1209.453000      12728.053
User2   90000.720     29700.237600     119700.958
User3   30581.300     5351.727500      35933.028
User4   50000.720     15000.216000     65000.936