SQL:为另外两列 A 和 B 的成对组合选择 C 列的运行总计



我正在尝试查询一个表并计算另外两列成对组合的列值的运行总和。

具体来说,给定下表:

CREATE TABLE test (
bucket int(10) NOT NULL,
label varchar(10) NOT NULL,
amount int(10) NOT NULL
);
INSERT INTO test VALUES
(1, "A", 1),
(1, "B", 2),
(1, "C", 3),
(2, "A", 4),
(2, "B", 5),
(2, "C", 6),
(3, "A", 7),
(3, "B", 8),
(3, "C", 9),
(4, "A", 10),
(4, "B", 11),
(4, "C", 12);

我想查询一个列,用于计算每个存储桶/标签对的累积总和。

换句话说,我希望能够编写一个查询,该查询选择存储桶、标签和第三列,该列是每个条目的"金额"列的累积总和,其标签与该行的标签匹配。例如,对于上面的示例,第三列应具有以下值:

1, 
2, 
3, 
5, 
7, 
9, 
12, 
15, 
18, 
22, 
26, 
30 

换句话说,值 5 是 1 和 4 的总和("A"标签的前两个金额(,值 7 是 2 和 5 的总和("B"标签的前两个金额(,依此类推。

我知道我可以通过执行以下操作来获取整个列的累积总和:

SELECT
*,
SUM(amount) OVER (
ORDER BY amount
) AS running_total
FROM test

但我不确定如何按标签拆分它。

任何帮助都非常感谢!

你需要一个partition by子句:

SELECT t.*,
SUM(amount) OVER (PARTITION BY label 
ORDER BY amount
) AS running_total
FROM test t
ORDER BY bucket, amount;

尽管ORDER BY amount适用于您的数据,但我认为您可能也真的需要存储桶:

SELECT t.*,
SUM(amount) OVER (PARTITION BY label 
ORDER BY bucket, amount
) AS running_total
FROM test t
ORDER BY bucket, amount;

这是一个数据库<>小提琴。 请注意,这使用 MySQL 8,因为您的创建/插入代码与 MySQL 兼容。

我不确定这有多优雅,您也没有指定您正在使用哪个 SQL 引擎。但这里有一个针对PostgreSQL的解决方案:

SELECT
*,
SUM(amount) OVER (
ORDER BY amount
) AS running_total,
(SELECT SUM (amount) AS bucket_total 
FROM test AS inner_test 
WHERE inner_test.label = outer_test.label 
AND inner_test.amount <= outer_test.amount)
FROM test AS outer_test

基本上,它汇总了与外部选择具有相同标签和相同或更少数量的内部选择的数量。

编辑:我把这个答案留在这里供参考,但更好的方法是@Gordon Linoff的答案。

最新更新