복붙노트

[SQL] MS SQL Server의 누적 총 [중복]

SQL

MS SQL Server의 누적 총 [중복]

나는 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;

미리 감사드립니다.

해결법

  1. ==============================

    1.같은 쿼리가 2012 년 이후에서 지원됩니다. 이전 버전에서는 여러 가지 방법이있다. http://www.sqlperformance.com/2012/07/t-sql-queries/running-totals 이것을 참조

    같은 쿼리가 2012 년 이후에서 지원됩니다. 이전 버전에서는 여러 가지 방법이있다. http://www.sqlperformance.com/2012/07/t-sql-queries/running-totals 이것을 참조

  2. ==============================

    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 바이올린 데모

  3. ==============================

    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 속도에 인덱스로 괜찮을 것 같네요!

  4. ==============================

    4.재귀 CTE에 대한 쿼리를 확인합니다.

    재귀 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
    
  5. ==============================

    5.사용 재귀 CTE는이를 달성하기 위해.

    사용 재귀 CTE는이를 달성하기 위해.

  6. ==============================

    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 - 다시 생각한다

    편집 - 지금 확인을 실행 : 라이브 바이올린 여기

    데이터를 생성

    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
    

    당신이 영업 이익에 대한 코멘트에서 언급 한 바와 같이 유사한 질문에 이렇게 여기있다 그 질문에 샘 사프란 앞으로 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 
    
  7. from https://stackoverflow.com/questions/11664142/cumulative-total-in-ms-sql-server by cc-by-sa and MIT license