正在计算数据分区的 运行 总数
Calculating running totals for partitions of data
我有 table 名为 #t1 和三列。 CODE、Column1 和 Column2。
create table #t1 (
CODE NVARCHAR(20),
COLUMN1 NUMERIC(18,2),
COLUMN2 NUMERIC(18,2)
)
我有一些数据:
INSERT INTO #t1 (CODE,COLUMN1,COLUMN2)
VALUES ('432', 0,100),
('TOTAL FOR 432',0,100),
('4320001',0,250),
('4320001',50,0),
('4320001',0,140),
('4320001',300,0),
('TOTAL FOR 4320001',350,390),
('432002',200,0),
('432002',0,100),
('TOTAL FOR 432002',200,100)
drop table #t1
我想要 4 列(名为 BALANCE)。余额必须是表示每组数据的两列(列 1 - 列 2)之间总计 运行 的列。每组总数必须从零开始。
输出:
CODE COLUMN1 COLUMN2 BALANCE
432 0.00 100.00 -100
TOTAL 432 0.00 100.00 -100
4320001 0.00 250.00 -250
4320001 50.00 0.00 -200
4320001 0.00 140.00 -340
4320001 300.00 0.00 -40
TOTAL 4320001 350.00 390.00 -40
432002 200.00 0.00 200
432002 0.00 100.00 100
TOTAL 432002 200.00 100.00 100
总计 432 后,它开始再次计算总计 4320001,然后再次计算总计 432002.....
我怎样才能得到这个结果?
我正在使用 MS SQL SERVER 2014
编辑:
到目前为止我已经尝试过了(但这并不好):
SUM(sum(column1)-sum(column2)) OVER(ORDER BY code rows UNBOUNDED PRECEDING) AS SALDO
您可以使用以下查询来获取预期的结果集:
SELECT CODE_NAME, COLUMN1, COLUMN2, BALANCE
FROM (
SELECT CODE, CODE AS CODE_NAME, 1 AS ORD, COLUMN1, COLUMN2,
SUM(COLUMN1 - COLUMN2)
OVER (PARTITION BY CODE ORDER BY id) AS BALANCE
FROM t1
UNION ALL
SELECT CODE, CONCAT ('TOTAL FOR ', CODE) AS CODE_NAME, 2 AS ORD,
SUM(COLUMN1), SUM(COLUMN2),
SUM(COLUMN1 - COLUMN2) AS BALANCE
FROM t1
GROUP BY CODE
) AS t
ORDER BY CODE, ORD
上面假设有一个自增PK列,id
,用来定义顺序。它还假定总聚合未存储在您的原始 table.
中
运行 总数可以使用 SUM
聚合函数的窗口版本轻松计算。 OVER
子句中的 PARTITION BY
导致每个 CODE
切片计算总计。 OVER
子句中的 ORDER BY id
是导致 运行 总计算的原因。
总计是通过单独的查询计算的。 ORD
字段帮助我们在执行 UNION ALL
后正确排序 CODE
个切片。
根据您的输出:)
DECLARE @t1 TABLE (
CODE nvarchar(20),
COLUMN1 numeric(18, 2),
COLUMN2 numeric(18, 2)
)
INSERT INTO @t1 (CODE, COLUMN1, COLUMN2)
VALUES ('432', 0, 100),
('TOTAL FOR 432', 0, 100),
('4320001', 0, 250),
('4320001', 50, 0),
('4320001', 0, 140),
('4320001', 300, 0),
('TOTAL FOR 4320001', 350, 390),
('432002', 200, 0),
('432002', 0, 100),
('TOTAL FOR 432002', 200, 100)
-- CTE
;
WITH CTE
AS (SELECT
*,
ROW_NUMBER() OVER (ORDER BY @@rowcount) RowNum -- Order as per the input
FROM @t1)
-- get from CTE
SELECT
*,
SUM(COLUMN1 - COLUMN2) OVER (PARTITION BY code ORDER BY RowNum) AS Balance --sum using PARTITION
FROM CTE
ORDER BY RowNum
我有 table 名为 #t1 和三列。 CODE、Column1 和 Column2。
create table #t1 (
CODE NVARCHAR(20),
COLUMN1 NUMERIC(18,2),
COLUMN2 NUMERIC(18,2)
)
我有一些数据:
INSERT INTO #t1 (CODE,COLUMN1,COLUMN2)
VALUES ('432', 0,100),
('TOTAL FOR 432',0,100),
('4320001',0,250),
('4320001',50,0),
('4320001',0,140),
('4320001',300,0),
('TOTAL FOR 4320001',350,390),
('432002',200,0),
('432002',0,100),
('TOTAL FOR 432002',200,100)
drop table #t1
我想要 4 列(名为 BALANCE)。余额必须是表示每组数据的两列(列 1 - 列 2)之间总计 运行 的列。每组总数必须从零开始。
输出:
CODE COLUMN1 COLUMN2 BALANCE
432 0.00 100.00 -100
TOTAL 432 0.00 100.00 -100
4320001 0.00 250.00 -250
4320001 50.00 0.00 -200
4320001 0.00 140.00 -340
4320001 300.00 0.00 -40
TOTAL 4320001 350.00 390.00 -40
432002 200.00 0.00 200
432002 0.00 100.00 100
TOTAL 432002 200.00 100.00 100
总计 432 后,它开始再次计算总计 4320001,然后再次计算总计 432002..... 我怎样才能得到这个结果?
我正在使用 MS SQL SERVER 2014
编辑: 到目前为止我已经尝试过了(但这并不好):
SUM(sum(column1)-sum(column2)) OVER(ORDER BY code rows UNBOUNDED PRECEDING) AS SALDO
您可以使用以下查询来获取预期的结果集:
SELECT CODE_NAME, COLUMN1, COLUMN2, BALANCE
FROM (
SELECT CODE, CODE AS CODE_NAME, 1 AS ORD, COLUMN1, COLUMN2,
SUM(COLUMN1 - COLUMN2)
OVER (PARTITION BY CODE ORDER BY id) AS BALANCE
FROM t1
UNION ALL
SELECT CODE, CONCAT ('TOTAL FOR ', CODE) AS CODE_NAME, 2 AS ORD,
SUM(COLUMN1), SUM(COLUMN2),
SUM(COLUMN1 - COLUMN2) AS BALANCE
FROM t1
GROUP BY CODE
) AS t
ORDER BY CODE, ORD
上面假设有一个自增PK列,id
,用来定义顺序。它还假定总聚合未存储在您的原始 table.
运行 总数可以使用 SUM
聚合函数的窗口版本轻松计算。 OVER
子句中的 PARTITION BY
导致每个 CODE
切片计算总计。 OVER
子句中的 ORDER BY id
是导致 运行 总计算的原因。
总计是通过单独的查询计算的。 ORD
字段帮助我们在执行 UNION ALL
后正确排序 CODE
个切片。
根据您的输出:)
DECLARE @t1 TABLE (
CODE nvarchar(20),
COLUMN1 numeric(18, 2),
COLUMN2 numeric(18, 2)
)
INSERT INTO @t1 (CODE, COLUMN1, COLUMN2)
VALUES ('432', 0, 100),
('TOTAL FOR 432', 0, 100),
('4320001', 0, 250),
('4320001', 50, 0),
('4320001', 0, 140),
('4320001', 300, 0),
('TOTAL FOR 4320001', 350, 390),
('432002', 200, 0),
('432002', 0, 100),
('TOTAL FOR 432002', 200, 100)
-- CTE
;
WITH CTE
AS (SELECT
*,
ROW_NUMBER() OVER (ORDER BY @@rowcount) RowNum -- Order as per the input
FROM @t1)
-- get from CTE
SELECT
*,
SUM(COLUMN1 - COLUMN2) OVER (PARTITION BY code ORDER BY RowNum) AS Balance --sum using PARTITION
FROM CTE
ORDER BY RowNum