SQL中的平板计算

时间:2018-07-03 17:56:11

标签: sql-server

DECLARE @TABLE TABLE
(
     SlabFrom INT
    ,SlabTo INT
    ,Amount DECIMAL(18,3)
)

INSERT INTO @TABLE (SlabFrom, SlabTo, Amount)

SELECT 0, 300000, 0.788
UNION ALL
SELECT 300001, 700000, 0.735
UNION ALL
SELECT 700001, 1300000, 0.683
UNION ALL 
SELECT 1300001, 9999999, 0.630

SELECT * FROM @TABLE

DECLARE @QUANTITY INT = 300001

我对sql很陌生,想编写一个while循环,在该循环中,我可以先检查数量是否小于SlabTo值(如果是),然后将记录插入我可以执行的某些临时表中。但是假设如果数量超过slabTo值,那么无论什么数量,我都只想插入等于SlabTo-SlabFrom值的数量,并保留在下一个slab中。我只想在while循环中这样做

例如。如果数量为300001,则与在第一个平板中一样,我们将检查SlabTo-SlabFrom,即300000-0 = 300000,因此对300000数量应用的费率为0.788, 现在剩余的1将进入下一个平板,其适用费率为0.735

任何人都可以协助进行此查询。

1 个答案:

答案 0 :(得分:1)

这是我的目标:

DECLARE @TABLE TABLE
(
     SlabFrom INT
    ,SlabTo INT
    ,Amount DECIMAL(18,3)
)

INSERT INTO @TABLE (SlabFrom, SlabTo, Amount)

SELECT 0, 300000, 0.788
UNION ALL
SELECT 300001, 700000, 0.735
UNION ALL
SELECT 700001, 1300000, 0.683
UNION ALL 
SELECT 1300001, 9999999, 0.630

SELECT * FROM @TABLE

DECLARE @QUANTITY INT = 300001

;with AmountsPerSection as
(
    select t.*
        , (select min(x) from (values (@Quantity - coalesce(nullif(t.SlabFrom, 0) - 1, 0)), (t.SlabTo)) y(x)) as AppliedAmount
    from @TABLE t
), cleansedAmountsPerSection as
(
    select SlabFrom
        , SlabTo
        , Amount
        , case when AppliedAmount < 0 then 0 else AppliedAmount end as AppliedAmount
    from AmountsPerSection
)
select *
    , AppliedAmount * Amount as Value
from cleansedAmountsPerSection

第一个CTE会算出每个桶中有多少钱。第二个删除任何负值。最后选择进行计算。