使用CTE分配额外的税分

时间:2012-06-22 18:55:25

标签: sql loops common-table-expression

我有一个像这样的税收数据表

DECLARE @TaxSummary TABLE(
    TaxRegionType           SMALLINT NOT NULL,
    ActualRegionTaxTotal    NUMERIC(10,2) NULL,
    LineRegionTaxTotal      NUMERIC(10,2) NULL,
    ExtendedRegionTaxTotal  Numeric(14,6) NULL
)

我有一定数量的分数可以分配给该表中的每个地区类型......假设我有5美分,所以我有

Declare @Cents int = 5

Declare @Delta = 0.01

目前我用这样的while循环更新表

SET @Count = 0
    WHILE (@Count < @Cents)
      BEGIN
        SET @Count = @Count + 1

            UPDATE @TaxSummary
            SET ActualRegionTaxTotal = ActualRegionTaxTotal + @Delta
            WHERE TaxRegionType =
            (SELECT TOP(1) TaxRegionType
            FROM @TaxSummary
            WHERE ExtendedRegionTaxTotal <> 0
            ORDER BY ExtendedRegionTaxTotal-ActualRegionTaxTotal DESC)

      END

有没有办法可以使用CTE完成?还是非循环?基本上我想在行的每一行中添加一分,差异最大,并继续添加最大差异的行,直到使用所有额外的分数。

2 个答案:

答案 0 :(得分:0)

这可能会为您提供一个帮助您入门的一般建议 - 只需在每行添加一个分数,直到内联视图中的行号等于您想要丢失的额外值:

declare @cents int = 5

select
region,
tax old_tax,
tax + case when rn <= @cents then 0.01 else 0 end new_tax

from
(
select
region, 
tax,
row_number () over (partition by null order by tax desc) rn

from 
dbo.taxsummary 
) d

答案 1 :(得分:0)

好的,这就是我所拥有的,它只为每个区域设置new_tax到10.01所以它只使用2美分而不是全部5 .....这就是为什么我很困惑...我错过了什么?< / p>

DECLARE
    @OrderTotalTax      NUMERIC(10,2),
    @CollectedTax       NUMERIC(10,2),
    @RegionTotalTax     NUMERIC(10,2)

DECLARE @TaxSummary TABLE
(
    TaxRegionType           SMALLINT NOT NULL,
    ActualRegionTaxTotal    NUMERIC(10,2) NULL,
    LineRegionTaxTotal      NUMERIC(10,2) NULL,
    ExtendedRegionTaxTotal  Numeric(14,6) NULL
)


insert into @TaxSummary (TaxRegionType, ActualRegionTaxTotal, LineRegionTaxTotal,
ExtendedRegionTaxTotal )
values ( 1, 10.00, 0, 10.04 )

insert into @TaxSummary (TaxRegionType, ActualRegionTaxTotal, LineRegionTaxTotal,
ExtendedRegionTaxTotal )
values ( 2, 10.00, 0, 10.01 )

-- RegionTotalTax = 20.00
SELECT @RegionTotalTax = SUM(ActualRegionTaxTotal) from @TaxSummary

Declare @Cents int = 0

set @OrderTotalTax = 20.05


-- Cents will be 20.05-20.00*100 = 5
SET @Cents = ABS((@OrderTotalTax - @RegionTotalTax) * 100)

-- Distribute one cent at a time
Declare @Delta DECIMAL(18,2) = 0.01

select
TaxRegionType,
ActualRegionTaxTotal old_tax,
ActualRegionTaxTotal + case when rn <= @Cents then 0.01 else 0 end new_tax
from
(
select
TaxRegionType, 
ActualRegionTaxTotal,
row_number () over (partition by null order by ExtendedRegionTaxTotal-
ActualRegionTaxTotal desc) rn
from 
@TaxSummary 
) d