你将如何从这个转换表中的列:
ColumnA ColumnB
2 a
3 b
4 c
5 d
1 a
对此:
ColumnA ColumnB
3 a
6(=3+3) b
10(=4+3+3) c
15(=5+4+3+3) d
我有兴趣看 esp。你会选择什么方法。
你将如何从这个转换表中的列:
ColumnA ColumnB
2 a
3 b
4 c
5 d
1 a
对此:
ColumnA ColumnB
3 a
6(=3+3) b
10(=4+3+3) c
15(=5+4+3+3) d
我有兴趣看 esp。你会选择什么方法。
像这样:
;WITH cte
AS
(
SELECT ColumnB, SUM(ColumnA) asum
FROM @t
gROUP BY ColumnB
), cteRanked AS
(
SELECT asum, ColumnB, ROW_NUMBER() OVER(ORDER BY ColumnB) rownum
FROM cte
)
SELECT (SELECT SUM(asum) FROM cteRanked c2 WHERE c2.rownum <= c1.rownum),
ColumnB
FROM cteRanked c1;
这应该给你:
ColumnA ColumnB
3 a
6 b
10 c
15 d
我通常会避免尝试这样做,但以下内容符合您的要求:
declare @T table (ColumnA int,ColumnB char(1))
insert into @T(ColumnA,ColumnB) values
(2 , 'a'),
(3 , 'b'),
(4 , 'c'),
(5 , 'd'),
(1, 'a')
;With Bs as (
select distinct ColumnB from @T
)
select
SUM(t.ColumnA),b.ColumnB
from
Bs b
inner join
@T t
on
b.ColumnB >= t.ColumnB
group by
b.ColumnB
结果:
ColumnB
----------- -------
3 a
6 b
10 c
15 d
对于小型数据集,这会很好。但对于较大的数据集,请注意表格的最后一行依赖于获取SUM
原始表格的全部内容。
不确定这是否是最佳的,但是(SQL Fiddle)怎么样:
SELECT x.A + COALESCE(SUM(y.A),0) ColumnA, x.ColumnB
FROM
(
SELECT SUM(ColumnA) A, ColumnB
FROM myTable
GROUP BY ColumnB
) x
LEFT OUTER JOIN
(
SELECT SUM(ColumnA) A, ColumnB
FROM myTable
GROUP BY ColumnB
) y ON y.ColumnB < x.ColumnB
GROUP BY x.ColumnB, x.A
试试下面的脚本,
DECLARE @T TABLE(ColumnA INT, ColumnB VARCHAR(50));
INSERT INTO @T VALUES
(2, 'a'),
(3, 'b'),
(4, 'c'),
(5, 'd'),
(1, 'a');
SELECT SUM(ColumnA) OVER(ORDER BY ColumnB) AS ColumnA,ColumnB
FROM ( SELECT SUM(ColumnA) AS ColumnA,ColumnB
FROM @T GROUP BY ColumnB )T
create table #T
(
ID int primary key,
ColumnA int,
ColumnB char(1)
);
insert into #T
select row_number() over(order by ColumnB),
sum(ColumnA) as ColumnA,
ColumnB
from YourTable
group by ColumnB;
with C as
(
select ID,
ColumnA,
ColumnB
from #T
where ID = 1
union all
select T.ID,
T.ColumnA + C.ColumnA,
T.ColumnB
from #T as T
inner join C
on T.ID = C.ID + 1
)
select ColumnA,
ColumnB
from C
option (maxrecursion 0);
drop table #T;
使用 SQL 服务器?所以
假设您有一个包含 3 列 C_1、C_2、C_3 并按 C_1 排序的表。只需使用 [Over (Order By C_1)] 为 C_3 的总和添加一列:
选择 C_1, C_2, C_3, Sum(C_3) Over (Order By C_1)
如果您也想要行号,请以相同的方式进行:
Select Row_Number() Over (Order By C_1), C_1, C_2, C_3, Sum(C_3) Over (Order By C_1)
如果您使用的是 SQL Server 2012 或更高版本,那么这将产生所需的结果。
DECLARE @t TABLE(
ColumnA int,
ColumnB varchar(50)
);
INSERT INTO @t VALUES
(2,'a'),
(3,'b'),
(4,'c'),
(5,'d'),
(1,'a');
SELECT
SUM(ColumnA) OVER (ORDER BY ColumnB ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) AS ColumnA,
ColumnB
FROM (
SELECT
ColumnB,
SUM(ColumnA) AS ColumnA
FROM @t
GROUP BY ColumnB
) DVTBL
ORDER BY ColumnB
DECLARE @t TABLE(ColumnA INT, ColumnB VARCHAR(50));
INSERT INTO @t VALUES
(2, 'a'),
(3 , 'b'),
(4 , 'c'),
(5 , 'd'),
(1 , 'a');
;WITH cte
AS
(
SELECT ColumnB, sum(ColumnA) value,ROW_NUMBER() OVER(ORDER BY ColumnB) sr_no FROM @t group by ColumnB
)
SELECT ColumnB
,SUM(value) OVER ( ORDER BY ColumnB ROWS BETWEEN UNBOUNDED PRECEDING AND 0 PRECEDING)
FROM cte c1;
最好的解决方案(最简单和最快的)是使用OVER(ORDER BY)
子句。
我将给出并解释我的问题和找到的解决方案。
我有一个包含一些年度交易的表格,其中包含以下列
Yearx INT
NoSeq INT
Amount DECIMAL(10,2)
Balance DECIMAL(10,2)
前三列有值;balance
列是空的。
问题
Balance
考虑到 1 月 1 日的第一个值是 5000 欧元,如何填写值?
例子
NoSeq Amount Balance
----- -------- ---------
1 120.00+ 5120.00+ <= 5000 + 120
2 16.00- 5104.00+ <= 5000 + 120 - 16
3 3000.00- 2104.00+ <= 5000 + 120 - 16 + 3000
4 640.00+ 2740.00+ <= 5000 + 120 - 16 + 3000 + 640
解决方案(基于 Abdul Rasheed 的回答)
WITH
t AS
(
SELECT NoSeq
,Amount
FROM payements
WHERE Yearx = 2021
)
SELECT NoSeq
,Amount
,1179.18 + SUM(Amount) OVER(ORDER BY NoSeq
ROWS BETWEEN UNBOUNDED PRECEDING
AND CURRENT ROW
) AS Balance
FROM t
考虑到在 PostGreSql 上ROW BETWEEN
使用 before 是默认的,previousSELECT
可以简化为
WITH
t AS
(
SELECT NoSeq
,Amount
FROM payements
WHERE Yearx = 2021
)
SELECT NoSeq
,Amount
,1179.18 + SUM(Amount) OVER(ORDER BY NoSeq) as balance
FROM t
第一部分(WITH 子句)用于定义OVER(ORDER BY)
在最终 SELECT 中应用的表。
第二部分使用临时T
表计算运行总和。
在我的情况下,WITH
子句不是必需的,SELECT
命令可以最终简化为以下 SQL 命令
SELECT NoSeq
,Amount
,1179.18 + SUM(Amount) OVER(ORDER BY NoSeq) as balance
FROM payements
WHERE Yearx = 2021
我在我的-应用程序中使用了最后一个SQL
命令。VB.Net
Postgresql
为了在 2010 年 1 月 1 日计算超过一年的已知Balance
价值,我使用以下 SQL 命令
SELECT Yearx
,NoSeq
,Amount
,-279.34 + SUM(Amount) OVER(ORDER BY Yearx,NoSeq) as balance
FROM payements
WHERE Yearx BETWEEN 2010 AND 2021
你也可以这样做:
WITH grpAllData
AS
(
SELECT ColumnB, SUM(ColumnA) grpValue
FROM table_Name
gROUP BY ColumnB
)
SELECT g.ColumnB, sum(grpValue) OVER(ORDER BY ColumnB) desireValue
FROM grpAllData g
order by ColumnB
在上面的查询中,我们首先聚合了同一组中的所有值,然后在最后的选择中只是对先前的结果应用了一个窗口函数。
这将基于对列的列累积总和进行分组。
请参阅下面的 SQL
SELECT product,
product_group,
fiscal_year,
Sum(quantity) OVER ( partition BY fiscal_year,a.product_group ORDER BY a.posting_date, a.product_group rows 100000000 PRECEDING) AS quantity
FROM report
WHERE
order by b.fiscal_year DESC
您可以使用以下简单的选择语句
SELECT COLUMN_A, COLUMN_B,
(SELECT SUM(COLUMN_B) FROM #TBL T2 WHERE T2.ID <= T1.ID) as SumofPreviousRow FROM #TBL T1;