-1

重複の可能性:
SqlServer で実行中の合計を計算する

ms-sql サーバーの列の累積 (実行中) 合計を取得する必要があります。つまり、「マーク」という名前の列がある場合、各行の累積合計に対応して、現在の行と前の行の合計になります。結合を使用せずに結果を得ることができますか? 私のクエリはかなり大きいからです。

サンプル テーブルとデータを含めました。

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;

前もって感謝します。

4

6 に答える 6

5

同じクエリが2012年以降サポートされます。古いバージョンでは、いくつかのアプローチがあります。これを参照してくださいhttp://www.sqlperformance.com/2012/07/t-sql-queries/running-totals

于 2012-07-26T07:11:50.553 に答える
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 フィドルのデモ

于 2012-07-26T07:49:54.303 に答える
1

参加しないとおっしゃいましたが、応募はどうですか?;)

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のインデックスがあれば、速度は大丈夫です。

于 2012-07-26T07:36:31.547 に答える
1

再帰 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
于 2012-07-26T09:10:04.077 に答える
0

これを実現するには、再帰的 CTE を使用します。

于 2012-07-26T07:14:37.577 に答える
0

結合を行うだけでは順序が保証されないようですが、最終的な答えはわかります:

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 ルールのようです - 再考します

編集- 現在は正常に動作しています: LIVE FIDDLE HERE

データの作成

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 へのコメントで述べたように、同様の質問がHERE ON SOにあります 。その質問では、Sam Saffron が を使用して実行中の合計を行う非常にエレガントな方法を提唱しました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 
于 2012-07-26T07:40:06.107 に答える