在示例中,我想从Subtracted
分组的表2中TABLE 1
的总和中减去ValueBefore
中的GroupID
值。从第一行减去余数,然后从组中的下一行减去该值(依此类推),直到减去总数。
有没有一种方法可以做到这一点而无需遍历行来获取其余部分?
我的表1:
TABLE 1 of subtracting value GroupID Subtracted 1 32 2 30
我的表2:
ID GroupID ValueBefore Reduction ValueAfter 1 1 10 -10 0 2 1 15 -15 0 3 1 5 -5 0 4 1 5 -2 3 5 2 40 -30 10 6 2 30 0 30
答案 0 :(得分:0)
一种方法是使用ValueBefore
来计算SELECT t2.ID, t2.GroupID, t2.ValueBefore, r.ValueBefore AS rValueBefore
FROM Table2 AS t2
LEFT JOIN Table2 AS r
ON t2.GroupID = r.GroupID AND t2.ID >= r.ID
ORDER BY t2.ID, r.ID
的总投放量。
此查询:
ID GroupID ValueBefore rValueBefore
------------------------------------
1 1 10 10
2 1 15 10
2 1 15 15
3 1 5 10
3 1 5 15
3 1 5 5
4 1 5 10
4 1 5 15
4 1 5 5
4 1 5 5
5 2 40 40
6 2 30 40
6 2 30 30
产生以下输出:
ID
如果您在SUM
上按rValueBefore
和SELECT t2.ID, t2.GroupID, t2.ValueBefore, SUM(r.ValueBefore) AS Total
FROM Table2 AS t2
LEFT JOIN Table2 AS r
ON t2.GroupID = r.GroupID AND t2.ID >= r.ID
GROUP BY t2.ID, t2.GroupID, t2.ValueBefore
分组,则可以计算运行总计:
ID GroupID ValueBefore Total
-----------------------------
1 1 10 10
2 1 15 25
3 1 5 30
4 1 5 35
5 2 40 40
6 2 30 70
输出:
ValueAfter
您现在可以使用以下方法计算SELECT t.ID, t.GroupID, t.ValueBefore, Total,
Subtracted,
CASE
WHEN Total - t1.Subtracted < 0 THEN 0
ELSE Total - t1.Subtracted
END AS ValueAfter
FROM
(
SELECT t2.ID, t2.GroupID, t2.ValueBefore, SUM(r.ValueBefore) AS Total
FROM Table2 AS t2
LEFT JOIN Table2 AS r
ON t2.GroupID = r.GroupID AND t2.ID >= r.ID
GROUP BY t2.ID, t2.GroupID, t2.ValueBefore
) as t
JOIN Table1 AS t1 ON t.GroupID = t1.GroupID
ORDER BY ID
:
ID GroupID ValueBefore Total Subtracted ValueAfter
-------------------------------------------------------
1 1 10 10 32 0
2 1 15 25 32 0
3 1 5 30 32 0
4 1 5 35 32 3
5 2 40 40 30 10
6 2 30 70 30 40
输出:
nil
答案 1 :(得分:0)
我将使用累加和和一些相对简单的比较:
select t2.*,
(case when t2.running_value - t2.valuebefore < t1.subtracted
then 0
when t2.running_value < t1.subtracted
then t2.running_value - t1.subtracted
else t2.valuebefore
end) as reduction,
(case when t2.running_value < t1.subtracted then 0
else t2.running_value - t1.subtracted
end) as ValueAfter
from (select t2.*,
sum(valuebefore) over (partition by groupid order by id) as running_value
from t2
) t2 join
t1
on t2.groupid = t1.groupid;