복붙노트

[SQL] 어떻게 커서를 사용하지 않고 SQL의 실행 합계를 계산합니까?

SQL

어떻게 커서를 사용하지 않고 SQL의 실행 합계를 계산합니까?

나는 간결 임시 테이블에서 모든 커서 설정하고 선택을 떠날거야. 기본적으로,이 코드는 거래 당 모든 거래에 대한 실행 균형을 계산합니다.

WHILE @@fetch_status = 0
BEGIN

    set @balance = @balance+@amount

    insert into @tblArTran values ( --from artran table
                @artranid, @trandate, @type, 
                @checkNumber, @refNumber,@custid,
                @amount, @taxAmount, @balance, @postedflag, @modifieddate )


    FETCH NEXT FROM artranCursor into 
            @artranid, @trandate, @type, @checkNumber, @refNumber,
            @amount, @taxAmount,@postedFlag,@custid, @modifieddate

END

다른 질문에 대한 답변에서이 코드에 의해 영감을,

SELECT @nvcConcatenated = @nvcConcatenated + C.CompanyName + ', '
FROM tblCompany C
WHERE C.CompanyID IN (1,2,3)

SQL 당신이 나의 의미를 얻는 경우에, 그것은 문자열을 연결하는 것 같은 방법으로 번호를 요약 할 수있는 능력을 가지고 있는지 궁금 해서요. 즉 커서를 사용하지 않고, 행 당 "실행 균형"을 만들 수있다.

그것은 수 있습니까?

해결법

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

    1.현재 지역 변수 솔루션 업데이트를 살펴 할 수 있습니다 : http://geekswithblogs.net/Rhames/archive/2008/10/28/calculating-running-totals-in-sql-server-2005--- 더 - optimal.aspx

    현재 지역 변수 솔루션 업데이트를 살펴 할 수 있습니다 : http://geekswithblogs.net/Rhames/archive/2008/10/28/calculating-running-totals-in-sql-server-2005--- 더 - optimal.aspx

    DECLARE @SalesTbl TABLE (DayCount smallint, Sales money, RunningTotal money)
    
    DECLARE @RunningTotal money
    
    SET @RunningTotal = 0
    
    INSERT INTO @SalesTbl 
    SELECT DayCount, Sales, null
    FROM Sales
    ORDER BY DayCount
    
    UPDATE @SalesTbl
    SET @RunningTotal = RunningTotal = @RunningTotal + Sales
    FROM @SalesTbl
    
    SELECT * FROM @SalesTbl
    

    다른 모든 방법을 능가 되나 보장은 행 순서에 대한 몇 가지 의문이있다. 임시 테이블은 비록 인덱스 때 잘 작동 보인다 ..

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

    2.SQL은 커서를 사용하지 않고 합계를 실행 만들 수 있지만이 커서 실제로 집합 기반 솔루션보다 더 확대됨에있는 몇 가지 경우 중 하나 (SQL 서버에서 현재 사용할 수있는 연산자 제공). 또는, CLR 기능은 때때로 잘 빛날 수 있습니다. Itzik 벤의 GaN 실행 집계에 SQL 서버 매거진의 우수한 시리즈를했다. 이 시리즈는 지난 달 체결,하지만 당신은 온라인 구독이 경우 당신은 모든 기사에 대한 액세스를 얻을 수 있습니다.

    SQL은 커서를 사용하지 않고 합계를 실행 만들 수 있지만이 커서 실제로 집합 기반 솔루션보다 더 확대됨에있는 몇 가지 경우 중 하나 (SQL 서버에서 현재 사용할 수있는 연산자 제공). 또는, CLR 기능은 때때로 잘 빛날 수 있습니다. Itzik 벤의 GaN 실행 집계에 SQL 서버 매거진의 우수한 시리즈를했다. 이 시리즈는 지난 달 체결,하지만 당신은 온라인 구독이 경우 당신은 모든 기사에 대한 액세스를 얻을 수 있습니다.

    편집 : 여기에 시리즈 (SQL CLR)에서 자신의 최신 기사입니다. 적은 6 달러보다 - - 당신이 한 달 동안 온라인 월간 패스를 구입하여 전체 시리즈에 액세스 할 수 있습니다 감안할 때 그것의 가치가 당신의 동안 모든 각도에서 문제를보고 관심이 있다면. Itzik는 마이크로 소프트 MVP와 매우 밝은 TSQL 코더입니다.

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

    3.오라클과 PostgreSQL 8.4에서는 윈도우 기능을 사용할 수 있습니다 :

    오라클과 PostgreSQL 8.4에서는 윈도우 기능을 사용할 수 있습니다 :

    SELECT  SUM(value) OVER (ORDER BY id)
    FROM    mytable
    

    MySQL은, 당신은 같은 목적을 위해 세션 변수를 사용할 수 있습니다 :

    SELECT  @sum := @sum + value
    FROM    (
            SELECT  @sum := 0
            ) vars, mytable
    ORDER BY
            id
    

    SQL 서버에서는 커서가 선호하는 솔루션입니다있는 작업의 드문 예입니다.

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

    4.각 레코드에 대한 누적 합계를 계산의 예,하지만 기록에 대한 주문 날짜가 같은 날짜에 경우에만. 주문 날짜가 다른 날되면, 다음 새 누적 합계가 시작되고 새로운 일 축적됩니다 (테이블 구조와 데이터를 가정)

    각 레코드에 대한 누적 합계를 계산의 예,하지만 기록에 대한 주문 날짜가 같은 날짜에 경우에만. 주문 날짜가 다른 날되면, 다음 새 누적 합계가 시작되고 새로운 일 축적됩니다 (테이블 구조와 데이터를 가정)

    select O.OrderId,
    convert(char(10),O.OrderDate,101) as 'Order Date',
    O.OrderAmt, 
    (select sum(OrderAmt) from Orders 
                          where OrderID <= O.OrderID and 
                               convert(char(10),OrderDate,101)
                             = convert(char(10),O.OrderDate,101))
                                   'Running Total' 
    from Orders O
    order by OrderID
    

    다음은 샘플 주문 표를 사용하여 쿼리에서 반환 된 결과는 다음과 같습니다

    OrderId     Order Date OrderAmt   Running Total                            
    ----------- ---------- ---------- ---------------
    1           10/11/2003 10.50      10.50
    2           10/11/2003 11.50      22.00
    3           10/11/2003 1.25       23.25
    4           10/12/2003 100.57     100.57
    5           10/12/2003 19.99      120.56
    6           10/13/2003 47.14      47.14
    7           10/13/2003 10.08      57.22
    8           10/13/2003 7.50       64.72
    9           10/13/2003 9.50       74.22
    

    참고는 "누적 합계는"10.50의 값로 시작, 다음 22.00되어, 모든 레코드가 같은 주문일 (2003년 10월 11일)를 갖고 있기 때문에 마지막으로, OrderID를 3 23.25이되고있다. OrderID를 4가 표시 될 때 실행중인 총 리셋하고, 누적 합계가 시작 다시. 이것에 OrderID 4는 주문일위한 다른 기간을 갖기 때문에 그 후, 일단 다시 상관 서브 쿼리를 사용하여 수행되는 각각의 고유 한 일이 누적 합계를 계산 한 2, 3 ORDERID 조건이 요구되는 추가, 비록 어느 다른 기록에 주문 날짜의 같은 날 할 필요가 있음을 확인했다. 이 WHERE 조건은 MM / DD / YYYY 포맷으로 주문일 잘라야로 변환 함수를 이용함으로써 달성된다.

  5. ==============================

    5.SQL 서버 2012 년까지 당신은 원래의 테이블에 대해 직접 합계 윈도 기능을 사용할 수 있습니다 :

    SQL 서버 2012 년까지 당신은 원래의 테이블에 대해 직접 합계 윈도 기능을 사용할 수 있습니다 :

    SELECT
       artranid,
       trandate,
       type,
       checkNumber,
       refNumber,
       custid,
       amount,
       taxAmount,
       Balance = Sum(amount) OVER (ORDER BY trandate ROWS UNBOUNDED PRECEDING),
       postedflag,
       modifieddate
    FROM
       dbo.Sales
    ;
    

    이것은 모든 솔루션에 비해 매우 잘 수행하고 "기발한 업데이트"에서 볼 수있는 오류의 가능성이 없습니다.

    가능하면 행 버전을 사용해야합니다; 범위 버전은 덜 잘 수행 할 수 있습니다.

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

    6.당신은 select 절에 상관 하위 쿼리를 포함 할 수 있습니다. (이것은 매우 큰 결과 집합에 대한 제대로 수행)하지만,

    당신은 select 절에 상관 하위 쿼리를 포함 할 수 있습니다. (이것은 매우 큰 결과 집합에 대한 제대로 수행)하지만,

       Select <other stuff>,
           (Select Sum(ColumnVal) From Table
            Where OrderColumn <= T.OrderColumn) As RunningTotal
       From Table T
       Order By OrderColumn
    
  7. ==============================

    7.현재, 실행중인 수를 할 수있는이 그것을 테이블이 큰 경우 모든 행에 대해 테이블을 스캔하는 빠른 때문에이 꽤 시간과 비용이 많이들 수 있다는 사실은 아니라는 것을 염두에 예를 들어 계속된다

    현재, 실행중인 수를 할 수있는이 그것을 테이블이 큰 경우 모든 행에 대해 테이블을 스캔하는 빠른 때문에이 꽤 시간과 비용이 많이들 수 있다는 사실은 아니라는 것을 염두에 예를 들어 계속된다

    create table #Test  (id int, Value decimal(16,4))
    insert #Test values(1,100)
    insert #Test values(2,100)
    insert #Test values(3,100)
    insert #Test values(4,200)
    insert #Test values(5,200)
    insert #Test values(6,200)
    insert #Test values(7,200)
    
    select *,(select sum(Value) from  #Test t2 where t2.id <=t1.id) as SumValues
     from #test t1
    
    id  Value       SumValues
    1   100.0000    100.0000
    2   100.0000    200.0000
    3   100.0000    300.0000
    4   200.0000    500.0000
    5   200.0000    700.0000
    6   200.0000    900.0000
    7   200.0000    1100.0000
    
  8. ==============================

    8.SQLTeam에 또한 실행 합계를 계산하는 방법에 대한 기사가있다. 일부 성능 측정과 함께, 그것을 할 수있는 3 가지 방법의 비교가있다 :

    SQLTeam에 또한 실행 합계를 계산하는 방법에 대한 기사가있다. 일부 성능 측정과 함께, 그것을 할 수있는 3 가지 방법의 비교가있다 :

    커서는 지금까지 다른 솔루션에 의해 능가하지만 커서를 사용하지해야하는 경우, 적어도 대안이있다.

  9. ==============================

    9.그 것을 SELECT @nvcConcatonated 비트는 하나의 연쇄 된 값을 반환한다. (이 당 행을 기준으로 중간 값을 계산이야 있지만, 당신은 단지 최종 값을 검색 할 수있어).

    그 것을 SELECT @nvcConcatonated 비트는 하나의 연쇄 된 값을 반환한다. (이 당 행을 기준으로 중간 값을 계산이야 있지만, 당신은 단지 최종 값을 검색 할 수있어).

    그래서, 대답은 전혀 생각하지 않습니다. 단일 최종 합계 값을 원하는 경우에 당신은 물론 단지 SUM을 사용합니다.

    난 그냥 당신이 '트릭'을 사용하여 할 수 없어 말하고, 당신이 그것을 할 수 없습니다 말하는 게 아니에요.

  10. ==============================

    10.변수를 사용하여 별도의 행이 서로 다른 프로세서에서 계산 얻을 수 있기 때문에 멀티 프로세서 시스템에서 실패 할 수있는 다음과 같은 본을 수행하는 동일한 시작 값을 사용하게 좋다. 나의 이해는 쿼리 힌트가 단일 스레드를 사용하도록 강제하는 데 사용할 수 있습니다,하지만 난 편리하게 정보를 필요가 없다는 것입니다.

    변수를 사용하여 별도의 행이 서로 다른 프로세서에서 계산 얻을 수 있기 때문에 멀티 프로세서 시스템에서 실패 할 수있는 다음과 같은 본을 수행하는 동일한 시작 값을 사용하게 좋다. 나의 이해는 쿼리 힌트가 단일 스레드를 사용하도록 강제하는 데 사용할 수 있습니다,하지만 난 편리하게 정보를 필요가 없다는 것입니다.

    UPDATE @SalesTbl   SET @RunningTotal = RunningTotal은 = @RunningTotal + 판매   @SalesTbl FROM

    사용하여 다른 옵션 중 하나 (커서, 윈도우 함수 또는 중첩 된 쿼리) 일반적으로 신뢰할 수있는 결과에 대한 안전한 내기 될 것입니다.

  11. ==============================

    11.TransactionDate는 양 양 + 거래에서 RunningTotal은 (트랜잭션의 합 x.amount 어디 x.TransactionDate <트랜잭션 X)을 선택

    TransactionDate는 양 양 + 거래에서 RunningTotal은 (트랜잭션의 합 x.amount 어디 x.TransactionDate <트랜잭션 X)을 선택

    어디     x.TransactionDate <거래 현재의 제외하고 이전의 모든 기록을 나타냅니다 어떤 조건이 될 수

  12. from https://stackoverflow.com/questions/1153879/how-do-i-calculate-a-running-total-in-sql-without-using-a-cursor by cc-by-sa and MIT license