26

你将如何从这个转换表中的列:

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。你会选择什么方法。

4

12 回答 12

21

像这样:

;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

这是一个现场演示

于 2012-10-01T07:10:03.430 回答
9

我通常会避免尝试这样做,但以下内容符合您的要求:

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原始表格的全部内容。

于 2012-10-01T07:12:20.517 回答
6

不确定这是否是最佳的,但是(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
于 2012-10-01T07:11:05.853 回答
4

试试下面的脚本,

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
于 2018-06-12T06:23:16.073 回答
3
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;
于 2012-10-01T07:17:43.127 回答
2

使用 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)

于 2019-01-21T08:07:26.343 回答
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
于 2020-01-15T11:56:13.913 回答
0
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;
于 2018-06-12T06:12:56.387 回答
0

最好的解决方案(最简单和最快的)是使用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.NetPostgresql

为了在 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
于 2022-02-18T11:10:14.717 回答
0

你也可以这样做:

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

在上面的查询中,我们首先聚合了同一组中的所有值,然后在最后的选择中只是对先前的结果应用了一个窗口函数。

于 2022-02-21T22:54:49.367 回答
-1

这将基于对列的列累积总和进行分组。

请参阅下面的 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
于 2020-02-11T15:20:57.513 回答
-2

您可以使用以下简单的选择语句

SELECT COLUMN_A, COLUMN_B, 
(SELECT SUM(COLUMN_B) FROM #TBL T2 WHERE T2.ID  <= T1.ID) as SumofPreviousRow FROM #TBL T1;
于 2015-11-20T11:29:46.140 回答