我有任意金额花费,比方说1000美元
我还有几十行,让我们说员工的薪水作为专栏
我如何按照优先顺序在员工中分配1000美元的预算,这样他们每个人都可以获得工资栏中的价值,直到钱全部用完为止?一旦预算全部用完,剩下的员工就会留下零。
Employee, Rank, Salary
John, 1, 500$
Anne, 2, 400$
Rob, 3, 300$
Bill, 4, 200$
结果应为:
John, 1, 500$, 500$
Anne, 2, 400$, 400$
Rob, 3, 300$, 100$ --Only 100 left in the budget
Bill, 4, 200$, 0$
知道如何在没有光标的情况下进行操作吗?
答案 0 :(得分:3)
这是一种方式。
CREATE TABLE #emp (Employee VARCHAR(10), Rank INT, Salary INT CHECK (Salary > 0));
INSERT INTO #emp
VALUES ('John',1,500),
('Anne',2,400),
('Rob',3,300 ),
('Bill',4,200);
DECLARE @Budget INT = 1000;
WITH T1 AS
( SELECT * ,
running_total = SUM(Salary) OVER (ORDER BY Rank
ROWS BETWEEN UNBOUNDED PRECEDING
AND CURRENT ROW)
FROM #emp ),
T2 AS
(
SELECT *,
prev_running_total = LAG(running_total) OVER (ORDER BY Rank)
FROM T1
)
SELECT Employee,
Rank,
Salary,
CASE
--run out
WHEN prev_running_total >= @Budget THEN 0
--budget left but not enough for whole salary
WHEN running_total > @Budget THEN @Budget - prev_running_total
--Can do full amount
ELSE Salary
END
FROM T2;
DROP TABLE #emp
答案 1 :(得分:0)
如果预算低于薪水
CASE
--run out
WHEN prev_running_total >= @Budget THEN 0
WHEN @Budget <= T2.Salary THEN @Budget
--budget left but not enough for whole salary
WHEN running_total > @Budget THEN @Budget - prev_running_total
--Can do full amount
ELSE Salary
END
答案 2 :(得分:0)
-- FOR EARLIER VERSIONS OF SQL SERVER (CTE SUPPORTED)
DECLARE @Budget INT = 905;
IF OBJECT_ID ('TEMPDB..#emp') IS NOT NULL
DROP TABLE #EMP
CREATE TABLE #emp (Employee VARCHAR(10), Rank INT, Salary INT CHECK (Salary > 0));
INSERT INTO #emp
VALUES ('John',1,500),
('Anne',2,400),
('Rob',3,300 ),
('Bill',4,200);
WITH T1 AS
( SELECT A.* ,
running_total = SUM(B.Salary) -- OVER (ORDER BY [Rank] )
--ROWS BETWEEN UNBOUNDED PRECEDING
--AND CURRENT ROW
--)
FROM #emp A
LEFT JOIN #emp B ON B.[Rank] <= A.[Rank]
GROUP BY A.Employee, A.[Rank], A.Salary
--ORDER BY 1,2
)
,
T2 AS
(
SELECT A.*, prev_running_total = B.running_total
FROM T1 A
LEFT JOIN T1 B ON B.[Rank] + 1 = A.[Rank]
)
SELECT Employee,
Rank,
Salary,
CASE
--run out
WHEN isnull(prev_running_total,0) >= @Budget THEN 0
--budget left but not enough for whole salary
WHEN running_total > @Budget THEN @Budget - isnull(prev_running_total, 0)
--Can do full amount
ELSE Salary
END Distribution
FROM T2
ORDER BY 2;
IF OBJECT_ID ('TEMPDB..#emp') IS NOT NULL
DROP TABLE #EMP