我试图做的基础基本上是让我创建的循环遍历表,但按组运行((将由每个Manager运行,然后重置变量并运行,直到不再运行)经理存在)。
以下是用于CURSOR循环的代码:
--Setting up table for LOOP
DECLARE @Running TABLE(BASManagerName VARCHAR(150), YearMonthDay DATE, CommissionAmount NUMERIC(16,2), LeftOverAmount NUMERIC(16,2), RunningTotal NUMERIC(16,2), Threshold INT, Payout NUMERIC(16,2), MyCounter INT)
DECLARE HotelThreshold CURSOR LOCAL
FOR
SELECT RowGrouping ,BASManagerName ,YearMonthDay ,CommissionAmount
FROM #HotelSumsNEWYearMonth
ORDER BY RowGrouping, BASManagerName, YearMonthDay
DECLARE @Rank INT
,@CursorManager VARCHAR(150)
,@YearMonthDay DATE
,@Total NUMERIC(16,2)
,@Threshold INT
,@LeftOverAmount NUMERIC(16,2)
,@RunningTotal NUMERIC(16,2)
,@Payout NUMERIC(16,2)
,@MyCounter INT
SET @Total = 0
SET @LeftOverAmount = 0
SET @RunningTotal = 0
SET @MyCounter = 0
SET @Payout = 0
SET @Threshold = 0
OPEN HotelThreshold
FETCH NEXT FROM HotelThreshold INTO @Rank, @CursorManager, @YearMonthDay, @Total
WHILE @@FETCH_STATUS = 0
BEGIN
IF CAST((@LeftOverAmount + @Total) / 50000 AS INT) < 1
BEGIN
SET @RunningTotal = (@LeftOverAmount + @Total)
SET @Threshold = 0
SET @Payout = 0
SET @LeftOverAmount = @RunningTotal - (@Threshold * 50000)
SET @MyCounter = @MyCounter + 1
END
ELSE IF CAST((@LeftOverAmount + @Total) / 50000 AS INT) >= 1
BEGIN
SET @RunningTotal = (@LeftOverAmount + @Total)
SET @Threshold = CASE WHEN CAST(@RunningTotal / 50000 AS INT) >= 1 THEN CAST(@RunningTotal / 50000 AS INT) * 1 ELSE 0 END
SET @Payout = @Threshold * 2500
SET @LeftOverAmount = @RunningTotal - (@Threshold * 50000)
SET @MyCounter = @MyCounter + 1
END
INSERT @Running VALUES (@CursorManager, @YearMonthDay, @Total, @LeftOverAmount, @RunningTotal, @Threshold, @Payout, @MyCounter)
FETCH NEXT FROM HotelThreshold INTO @Rank, @CursorManager, @YearMonthDay, @Total
END
CLOSE HotelThreshold
DEALLOCATE HotelThreshold
DROP TABLE #NewRunning
SELECT *
INTO #NewRunning
FROM @Running
SELECT * FROM #NewRunning
这里是#HotelSumsNewYearMonth表的DDL,该表填充了Cursor以及表中数据的示例:
+-------------+----------------+--------------+-----------+------------------+
| RowGrouping | BASManagerName | YearMonthDay | YearMonth | CommissionAmount |
+-------------+----------------+--------------+-----------+------------------+
| 1 | Debbie | 7/1/2019 | 2019-07 | 33508.83 |
| 1 | Debbie | 8/1/2019 | 2019-08 | 34240.37 |
| 1 | Debbie | 9/1/2019 | 2019-09 | 19282.73 |
| 1 | Debbie | 10/1/2019 | 2019-10 | 0 |
| 1 | Debbie | 11/1/2019 | 2019-11 | 0 |
| 2 | Pam | 7/1/2019 | 2019-07 | 321.23 |
| 2 | Pam | 8/1/2019 | 2019-08 | 952.89 |
| 2 | Pam | 9/1/2019 | 2019-09 | 601.84 |
| 2 | Pam | 10/1/2019 | 2019-10 | 56.94 |
| 2 | Pam | 11/1/2019 | 2019-11 | 76.83 |
+-------------+----------------+--------------+-----------+------------------+
循环代码的实现说明:
循环实现的结果是,它将创建BASManager每月赚取的佣金的连续总额。但是有一条条款规定,如果佣金超过5万,他们将在该月收到2500的付款。然后必须要做的是,达到50K后的一个月的运行总计,但是我会从运行总计中减去该阈值达到目标的很多倍,并从那时开始一直保持滚动。
输出错误,因为循环仅针对整个表而不是针对每个组运行:
+----------------+--------------+------------------+----------------+--------------+-----------+--------+-----------+
| BASManagerName | YearMonthDay | CommissionAmount | LeftOverAmount | RunningTotal | Threshold | Payout | MyCounter |
+----------------+--------------+------------------+----------------+--------------+-----------+--------+-----------+
| Debbie | 7/1/2019 | 33508.83 | 33508.83 | 33508.83 | 0 | 0 | 1 |
| Debbie | 8/1/2019 | 34240.37 | 17749.2 | 67749.2 | 1 | 2500 | 2 |
| Debbie | 9/1/2019 | 19282.73 | 37031.93 | 37031.93 | 0 | 0 | 3 |
| Debbie | 10/1/2019 | 0 | 37031.93 | 37031.93 | 0 | 0 | 4 |
| Debbie | 11/1/2019 | 0 | 37031.93 | 37031.93 | 0 | 0 | 5 |
| Pam | 7/1/2019 | 321.23 | 37353.16 | 37353.16 | 0 | 0 | 6 |
| Pam | 8/1/2019 | 952.89 | 38306.05 | 38306.05 | 0 | 0 | 7 |
| Pam | 9/1/2019 | 601.84 | 38907.89 | 38907.89 | 0 | 0 | 8 |
| Pam | 10/1/2019 | 56.94 | 38964.83 | 38964.83 | 0 | 0 | 9 |
| Pam | 11/1/2019 | 76.83 | 39041.66 | 39041.66 | 0 | 0 | 10 |
+----------------+--------------+------------------+----------------+--------------+-----------+--------+-----------+
[您可以看到Debbie的运行总金额处于37031.93的正确点,她已经在2019年8月1日收到付款,金额超过50,000,然后从运行总金额中减去50,000,再减去下个月的余额佣金总计为37031.93。
[我想/需要发生的事情]十一月过去了,一旦循环开始,Pam的运行便是将变量重置为0并从Pam的数据重新开始。但是,您可以看到当前它正在保持Debbie的运行总计,并以此为基础来开始Pam的计算。
使用窗口功能!游标不是必需的,大多数多余的列也不需要。
select t.*,
(floor(running_commissionamount / 50000) - floor( (running_commissionamount - commissionamount) / 50000)
) * 2500 as this_months_commission
from (select t.*,
sum(commissionamount) over (partition by rowgrouping order by yearmonth) as running_commissionamount
from t
) t
这里唯一真正棘手的部分是计算通过的50,000个阈值的数量。