在MS SQL Server的累积合计[复制]在MS SQL Server的累积合计[复制](Cum

2019-05-12 11:10发布

可能重复:
计算SqlServer的运行总计

我需要累积(运行)总在MS-SQL Server中的列。 也就是说,如果有一个名为“标志”,那么对应于每一行累计和列将当前和以前行的总和。 我们能否实现,而无需使用连接的结果呢? 因为我的查询是相当大的。

我已经包括示例表和数据:

CREATE TABLE "SCORE_CHART" 
   (    
        "STUDENT_NAME" NVARCHAR(20), 
        "MARKS" INT
   )

INSERT INTO SCORE_CHART (STUDENT_NAME, MARKS) VALUES ('STUD1', 95);
INSERT INTO SCORE_CHART (STUDENT_NAME, MARKS) VALUES ('STUD2', 90);
INSERT INTO SCORE_CHART (STUDENT_NAME, MARKS) VALUES ('STUD3', 98);

SELECT STUDENT_NAME, MARKS FROM SCORE_CHART;

预期结果:

在甲骨文很容易写,如:

SELECT 
  STUDENT_NAME,
  MARKS,
  SUM(MARKS) OVER (ORDER BY STUDENT_NAME) CUM_SUM
FROM SCORE_CHART
ORDER BY STUDENT_NAME;

提前致谢。

Answer 1:

同样的查询,从2012年起支持。 在旧版本中有几种方法。 请参阅本http://www.sqlperformance.com/2012/07/t-sql-queries/running-totals



Answer 2:

试试这个:

你可以通过加入相同的表本身获得的累计总和

SELECT S1.STUDENT_NAME, S1.MARKS ,sum(S2.MARKS) CUM_SUM
FROM SCORE_CHART S1 join SCORE_CHART S2
on S1.STUDENT_NAME>=S2.STUDENT_NAME
group by S1.STUDENT_NAME, S1.MARKS 
order by S1.STUDENT_NAME, S1.MARKS

SQL小提琴演示



Answer 3:

你说没有加入,那一个申请? ;)

SELECT STUDENT_NAME, MARKS, running.total
FROM SCORE_CHART a
cross apply 
(
    select SUM(marks) total 
    from score_chart b
    where b.student_name <= a.student_name
) running
ORDER BY STUDENT_NAME;

随着student_name速度的指标应该没问题!



Answer 4:

检查递归CTE查询。

;with CTE as (select ROW_NUMBER() over (order by (select 0)) as id,STUDENT_NAME,MARKS from SCORE_CHART)
,CTE1 as (

select id,STUDENT_NAME,marks,marks as CUM_SUM from CTE where id=1
UNION ALL
select c.id,c.STUDENT_NAME,c.marks,c.marks+c1.CUM_SUM as CUM_SUM from CTE1 c1 inner join CTE c on c.id-1=c1.id)
select * from CTE1


Answer 5:

使用递归CTE来实现这一目标。



Answer 6:

只是做了加入似乎并不保证订单,但与最终的答案确定出现:

select 
  x.STUDENT_NAME
  , sum(y.marks) marks
from 
    SCORE_CHART x
       join SCORE_CHART y
          on x.STUDENT_NAME <= y.STUDENT_NAME
group by x.STUDENT_NAME
order by x.STUDENT_NAME

只是似乎是NO JOINS规则 - 将重新考虑

编辑 - OK,现在运行的: 住在这里FIDDLE

创建数据

CREATE TABLE "SCORE_CHART"     
(             
  "STUDENT_NAME" NVARCHAR(20),          
  "MARKS" INT    
)  
INSERT INTO SCORE_CHART (STUDENT_NAME, MARKS) 
VALUES 
('STUD1', 95),
('STUD2', 90),
('STUD3', 98)

使用递归CTE:

 ;WITH 
    init_cte(row,STUDENT_NAME,MARKS) 
    AS
        (
        SELECT 
        ROW_NUMBER() OVER (ORDER BY STUDENT_NAME),
        STUDENT_NAME,
        MARKS
        FROM SCORE_CHART
        )
    ,MinMax_cte(MinRow,MaxRow)  AS (SELECT MIN(row),MAX(row) FROM init_cte)

    ,recursive_cte (row,STUDENT_NAME,MARKS,RUNNING_MARKS) AS 
      (
         SELECT row,STUDENT_NAME,MARKS,MARKS 
            FROM init_cte 
            WHERE row = (SELECT MinRow FROM  MinMax_cte) 
         UNION ALL
         SELECT Y.row,y.STUDENT_NAME,y.MARKS,x.RUNNING_MARKS + y.MARKS
            FROM recursive_cte x
            INNER JOIN init_cte y
                ON y.row = x.row + 1
            WHERE y.row <= (SELECT [MaxRow] from MinMax_cte)
      )
SELECT * FROM recursive_cte

正如你OP的留言中提到有一个类似的问题在这里SO在这个问题萨姆藏红花提出这样一个正在运行的使用总的非常优雅的方式UPDATE 。 这是适用于您的数据:

使用上面,但与UPDATE招创建相同的数据:

CREATE TABLE #t ( ROW int, STUDENT_NAME NVARCHAR(20) , MARKS int, MARKS_RUNNING int) 
INSERT INTO #t
SELECT
        ROW_NUMBER() OVER (ORDER BY STUDENT_NAME),
        STUDENT_NAME, 
        MARKS,
        0
FROM SCORE_CHART

DECLARE @total int  
SET @total = 0 
UPDATE #t SET marksrunning = @total, @total = @total + MARKS   

SELECT * FROM #t 


文章来源: Cumulative Total in MS Sql server [duplicate]