2017-09-22 7 views
1

나는 회사 kardex를 재건하려고하고있다. 나는 특정 Datetime에서 각 트랜잭션에 대한 평균 비용을 고려해야하는 "Average Cost Method"를 사용해야합니다.재건 회사 kardex

모든 인바운드/아웃 바운드 인벤토리 트랜잭션 (모든 동작)이있는 간단한 테이블이 있습니다.

모든 수신 트랜잭션 (구매)은 해당 송장에서 단위 비용을 받음으로써 올바르게 가격이 책정됩니다.

문제 : 모든 판매 트랜잭션 (나가는 인벤토리)에는 단위 비용이 없습니다 (해당 비용을 다시 작성해야하기 때문에). 커서를 사용할 수는 있지만 성능 문제는 모두 알고 있습니다.

나 자신을 더 잘 설명 할 수 있도록 간단한 데이터를 준비했습니다. 모든 판매 (발신 트랜잭션)에는 비용이 들지 않으며 간단한 창 함수를 사용하면 각 행이 이전 계산에 의존하기 때문에 도움이되지 않는다고 생각합니다. 그래서 이전 계산에 기초한 계산이 필요합니다. ??

DECLARE @Resultado TABLE (Row_ID BIGINT IDENTITY NOT NULL PRIMARY KEY, Inventory_Name VARCHAR(100), Transaction_Date DATETIME, DIRECTION BIT, Transaction_Name VARCHAR(100),Transaction_Quantity INT, Transaction_UnitCost NUMERIC(18,2), Transaction_Amount NUMERIC(18,2), AVERAGE_UNITCOST_AT_TRANSACTION_DATE NUMERIC(18,2)) 

INSERT INTO @Resultado (Inventory_Name , Transaction_Date , DIRECTION , Transaction_Name , Transaction_Quantity , Transaction_UnitCost, Transaction_Amount, AVERAGE_UNITCOST_AT_TRANSACTION_DATE) 
SELECT 'COMPUTER', '2017-01-01', 1, 'INCOMING PRODUCT; PRUCHASE', 100, 10, 100 * 10, 10 
UNION ALL SELECT 'COMPUTER', '2017-01-02', 1, 'INCOMING PRODUCT; PURCHASE', 105, 11, 105 * 11, 10.51 
UNION ALL SELECT 'COMPUTER', '2017-01-03', 1, 'INCOMING PRODUCT; PURCHASE', 110, 12, 110 * 12, 11.03 
UNION ALL SELECT 'COMPUTER', '2017-01-04', 0, 'OUTGOING PRODUCT; SALES', -200, NULL, NULL, NULL 
UNION ALL SELECT 'COMPUTER', '2017-01-05', 0, 'OUTGOING PRODUCT; SALES', -50, NULL, NULL, NULL 
UNION ALL SELECT 'COMPUTER', '2017-01-06', 1, 'INCOMING PRODUCT; PURCHASE', 110, 10, 110 * 10, NULL 
UNION ALL SELECT 'COMPUTER', '2017-01-07', 0, 'OUTGOING PRODUCT; SALES', -20, NULL, NULL, NULL 
UNION ALL SELECT 'COMPUTER', '2017-01-08', 0, 'OUTGOING PRODUCT; SALES', -20, NULL, NULL, NULL 
UNION ALL SELECT 'COMPUTER', '2017-01-09', 0, 'OUTGOING PRODUCT; SALES', -20, NULL, NULL, NULL 

SELECT * FROM @Resultado 
+0

Microsoft SQL Server 2012 Standard –

+1

테스트 데이터에서 좋은 결과를 얻었습니다. 예상되는 결과를 텍스트로 추가하고 함께 설명하십시오. – TheGameiswar

답변

1

팁 : 귀하의 질문에 예상되는 결과가 포함되어 있다면 도움이되었을 것입니다. 당신을 얻을해야

이 공통 테이블 식 (CTE)가 시작 :

with CTE as (
    select Row_Id, Inventory_Name, Transaction_Date, Direction, Transaction_Name, 
    Transaction_Quantity, Transaction_UnitCost, 
    Transaction_Quantity as QuantityOnHand, 
    Transaction_UnitCost as AverageUnitCost 
    from @Resultado 
    where Direction = 1 and Row_Id = 1 -- Starting condition for your single product sample data. 
    union all 
    select R.Row_ID, R.Inventory_Name, R.Transaction_Date, R.Direction, R.Transaction_Name, 
    R.Transaction_Quantity, R.Transaction_UnitCost, 
    -- The TransactionQuantity is already signed, so there is no need to multiple it by (Direction * 2 - 1) . 
    CTE.QuantityOnHand + R.Transaction_Quantity, 
    -- My accounting is pretty rusty, but this should do some sort of useful averaging. 
    Cast(case 
     when R.Direction = 0 then CTE.AverageUnitCost -- Sales don't affect the average unit cost. 
     else (CTE.AverageUnitCost * CTE.QuantityOnHand + R.Transaction_UnitCost * R.Transaction_Quantity)/
     (CTE.QuantityOnHand + R.Transaction_Quantity) end 
     as Numeric(18,2)) 
    from CTE inner join 
     @Resultado as R on R.Row_Id = CTE.Row_Id + 1 -- Row by row. 
    ) 
    select Row_Id, Inventory_Name, Transaction_Date, Direction, Transaction_Name, Transaction_Quantity, Transaction_UnitCost, 
    QuantityOnHand, AverageUnitCost 
    from CTE; 

당신은 당신의 select 문장의 끝에 세미콜론을 추가 한 후 샘플 데이터에 대해 실행할 수 있습니다.

첫 번째 행에서 계산을 시작해야하기 때문에 성능이 저하 될 수 있습니다. QuantityOnHandAveragreUnitCost을 유지 관리하기 위해 열을 추가하면 새로운 거래가 발생할 때 데이터를 업데이트 할 수 있습니다. 방아쇠로. 업데이트 및 삭제 작업은 처음부터 다시 계산해야 할 수 있습니다.

현대적인 솔루션은 Lead/Lag을 사용하지만 SQL Server 2008 R2로 되돌아갑니다.

+0

이 쿼리를 내가 원하는 해결책으로 확인합니다. 아주 많이. 내 데이터베이스의 일부 특정 시나리오에 적용해야하기 때문에 약간의 변경 작업을 수행했지만이 쿼리를 통해 모든 것이 가능해졌습니다. 다시, 감사합니다! –

+0

@LuisGilbert 글쓰기 방향으로 당신을 지적했기 때문에 기쁩니다. 대답을 수락하는 것은 StackOverflow의 예절에 포함됩니다. [답변 수락 방법은 무엇입니까?] (http://meta.stackoverflow.com/questions/5234/how-does-accepting-an-answer-work)를 참조하십시오. – HABO

+0

죄송합니다. 나는 새로운 질문을 게시하고 있습니다. 답변을 수락했습니다. 다시 한 번 감사드립니다! –