2

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

具体来说,给定下表:

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

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

任何帮助深表感谢!

4

2 回答 2

2

我不确定这有多优雅,您也没有指定您使用的是哪个 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's answer

于 2019-08-10T02:52:03.763 回答
2

你想要一个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;

是一个 db<>fiddle。请注意,这使用 MySQL 8,因为您的创建/插入代码与 MySQL 兼容。

于 2019-08-10T11:48:27.383 回答