Select 行,直到 运行 总和达到特定值
Select rows until running sum reaches specific value
我有以下数据:
DECLARE @t TABLE (usr VARCHAR(100), dt DATE, amount INT);
INSERT INTO @t VALUES
('a', '2018-01-01', 100), -- 100
('a', '2018-02-01', 100), -- 200
('a', '2018-03-01', 100), -- 300
('a', '2018-04-01', 100), -- 400
('a', '2018-05-01', 100), -- 500
('b', '2018-01-01', 150), -- 150
('b', '2018-02-01', 150), -- 300
('b', '2018-03-01', 150), -- 450
('b', '2018-04-01', 150), -- 600
('b', '2018-05-01', 150); -- 750
还有一个值,例如 300 或 301(用户变量或列)。我想要 select 行,直到 运行 总金额达到指定值,具有以下扭曲:
- 对于 300,我想 select a 的前 3 行和 b 的前 2 行
- 对于 301,我想 select a 的前 4 行和 b 的前 3 行
这应该很简单,但我找到的解决方案无法处理第二种情况。
DECLARE @t TABLE (usr VARCHAR(100), dt DATE, amount INT);
INSERT INTO @t VALUES
('a', '2018-01-01', 100), -- 100
('a', '2018-02-01', 100), -- 200
('a', '2018-03-01', 100), -- 300
('a', '2018-04-01', 100), -- 400
('a', '2018-05-01', 100), -- 500
('b', '2018-01-01', 150), -- 150
('b', '2018-02-01', 150), -- 300
('b', '2018-03-01', 150), -- 450
('b', '2018-04-01', 150), -- 600
('b', '2018-05-01', 150); -- 750
DECLARE @Total INT = 301;
WITH cte AS
(
SELECT *, SUM(amount) OVER (PARTITION BY usr ORDER BY dt) AS RunTotal
FROM @t
)
SELECT *
FROM cte
WHERE cte.RunTotal - cte.amount < @Total -- running total for previous row is less
-- than @Total then include current row
DECLARE @t TABLE (usr VARCHAR(100), dt DATE, amount INT);
INSERT INTO @t VALUES
('a', '2018-01-01', 100), -- 100
('a', '2018-02-01', 100), -- 200
('a', '2018-03-01', 100), -- 300
('a', '2018-04-01', 100), -- 400
('a', '2018-05-01', 100), -- 500
('b', '2018-01-01', 150), -- 150
('b', '2018-02-01', 150), -- 300
('b', '2018-03-01', 150), -- 450
('b', '2018-04-01', 150), -- 600
('b', '2018-05-01', 150); -- 750
declare @target int = 300;
with cte_RunningTotal as
(
select
usr,
dt,
amount,
sum(amount) over (partition by usr order by dt rows unbounded preceding) as runningTotal
from @t
)
select *
from cte_RunningTotal
where runningTotal < @target + amount
order by usr, dt
我有以下数据:
DECLARE @t TABLE (usr VARCHAR(100), dt DATE, amount INT);
INSERT INTO @t VALUES
('a', '2018-01-01', 100), -- 100
('a', '2018-02-01', 100), -- 200
('a', '2018-03-01', 100), -- 300
('a', '2018-04-01', 100), -- 400
('a', '2018-05-01', 100), -- 500
('b', '2018-01-01', 150), -- 150
('b', '2018-02-01', 150), -- 300
('b', '2018-03-01', 150), -- 450
('b', '2018-04-01', 150), -- 600
('b', '2018-05-01', 150); -- 750
还有一个值,例如 300 或 301(用户变量或列)。我想要 select 行,直到 运行 总金额达到指定值,具有以下扭曲:
- 对于 300,我想 select a 的前 3 行和 b 的前 2 行
- 对于 301,我想 select a 的前 4 行和 b 的前 3 行
这应该很简单,但我找到的解决方案无法处理第二种情况。
DECLARE @t TABLE (usr VARCHAR(100), dt DATE, amount INT);
INSERT INTO @t VALUES
('a', '2018-01-01', 100), -- 100
('a', '2018-02-01', 100), -- 200
('a', '2018-03-01', 100), -- 300
('a', '2018-04-01', 100), -- 400
('a', '2018-05-01', 100), -- 500
('b', '2018-01-01', 150), -- 150
('b', '2018-02-01', 150), -- 300
('b', '2018-03-01', 150), -- 450
('b', '2018-04-01', 150), -- 600
('b', '2018-05-01', 150); -- 750
DECLARE @Total INT = 301;
WITH cte AS
(
SELECT *, SUM(amount) OVER (PARTITION BY usr ORDER BY dt) AS RunTotal
FROM @t
)
SELECT *
FROM cte
WHERE cte.RunTotal - cte.amount < @Total -- running total for previous row is less
-- than @Total then include current row
DECLARE @t TABLE (usr VARCHAR(100), dt DATE, amount INT);
INSERT INTO @t VALUES
('a', '2018-01-01', 100), -- 100
('a', '2018-02-01', 100), -- 200
('a', '2018-03-01', 100), -- 300
('a', '2018-04-01', 100), -- 400
('a', '2018-05-01', 100), -- 500
('b', '2018-01-01', 150), -- 150
('b', '2018-02-01', 150), -- 300
('b', '2018-03-01', 150), -- 450
('b', '2018-04-01', 150), -- 600
('b', '2018-05-01', 150); -- 750
declare @target int = 300;
with cte_RunningTotal as
(
select
usr,
dt,
amount,
sum(amount) over (partition by usr order by dt rows unbounded preceding) as runningTotal
from @t
)
select *
from cte_RunningTotal
where runningTotal < @target + amount
order by usr, dt