Более простой способ решить сценарий без курсора - PullRequest
0 голосов
/ 02 марта 2020

Давайте рассмотрим одну таблицу

Date        Type    TransId     Qty  UnitCost   Total
01/01/2020  OPEN    IN33433     100  12         1200   --IN,UnitCost is fixed
19/03/2020  PUR     IN31134     200  12.5       2500   --IN,UnitCost is fixed
21/03/2020  DEL     OUT24443    250  12.33      3082.5 --OUT unit cost calculated
25/03/2020  DEL     OUT28668    10   12.33      123.3  --OUT unit cost calculated
26/03/2020  SAL     OUT35448    23   12.33      283.59 --OUT unit cost calculated
30/03/2020  TRSFR   IN83588     12   12.45      149.4  --IN, UnitCost is fixed

В таблице приведены записи транзакции инвентаризации. Допустим, типы IN OPEN, PUR, TRSFR, ADJIN и OUT Типы DEL, SAL, ADJOUT

Здесь стоимость единицы для всех транзакций IN фиксирована. Это означает, что мы получим это значение откуда-то и нам не нужно об этом беспокоиться.

Но для OUT-транзакций рассчитываются удельные затраты. Для лучшего понимания расчета рассмотрим пример. Первая OUT-транзакция 21.03.2020 с типом DEL. Формула для расчета единичной стоимости для этой транзакции OUT:

сумма всех итогов транзакции IN, произошедшей до и после любой OUT / суммы Qty всех транзакций IN, произошедшей до и после любой OUT

Таким образом, unitcost = (1200 + 2500) / (100 + 200) = 12,33 .

И затем транзакция IN произошла 30/03/2020 с Тип TRSFR. Для этого, как я уже говорил ранее, стоимость единицы является фиксированной. Теперь для любой произошедшей транзакции мы рассмотрим стоимость за единицу 12,45 (149,4 / 12).

Надеюсь, это понятно. Мне нужно решение, чтобы рассчитать и получить стоимость единицы без CURSOR. Допустим, мне нужно получить стоимость единицы для транзакции, которая должна произойти 20/04/2020 типа DEL (то есть OUT)

Ответы [ 2 ]

0 голосов
/ 02 марта 2020

Пример данных

create table #purchases
(
Date varchar(20),
Type varchar(10),
Transid varchar(100),
Qty int,
UnitCost float,
Total float
)

insert into #purchases values('01/01/2020','OPEN',    'IN33433',     100 , 12     ,    1200)   
insert into #purchases values('19/03/2020','PUR'  ,   'IN31134',     200 , 12.5   ,    2500)   
insert into #purchases values('21/03/2020','DEL'  ,   'OUT24443',    250 , 12.33  ,    3082.5)
insert into #purchases values('25/03/2020','DEL'   ,  'OUT28668',    10  , 12.33  ,    123.3)  
insert into #purchases values('26/03/2020','SAL'   ,  'OUT35448',    23  , 12.33  ,    283.59) 
insert into #purchases values('30/03/2020','TRSFR'  , 'IN83588' ,    12  , 12.45  ,    149.4) 

Запрос

select ROW_NUMBER() over (order by Date desc) as Rn,* into #temp
from #purchases


declare @latestOut int 
select @latestOut=Rn from #temp where  Type in ('DEL','SAL','ADJOUT') order by Rn desc


select SUM(Total)/Sum(Qty) as [Output] from #temp where RN<@latestOut
0 голосов
/ 02 марта 2020

Вы можете сделать это, используя несколько подзапросов, как показано ниже.

DECLARE @SampleTable TABLE
(
    Date            DATETIME,
    Type            VARCHAR(100),
    TransId         VARCHAR(100),
    Qty             INT,
    UnitCost        MONEY,
    Total           MONEY
)

INSERT INTO @SampleTable VALUES
('2020-01-01', 'OPEN',  'IN33433',     100 , 12    ,     1200  ), --IN,UnitCost is fixed
('2020-03-19', 'PUR',   'IN31134',     200 , 12.5  ,     2500  ), --IN,UnitCost is fixed
('2020-03-21', 'DEL',   'OUT24443',    250 , 12.33 ,     3082.5), --OUT unit cost calculated
('2020-03-25', 'DEL',   'OUT28668',    10  , 12.33 ,     123.3 ), --OUT unit cost calculated
('2020-03-26', 'SAL',   'OUT35448',    23  , 12.33 ,     283.59), --OUT unit cost calculated
('2020-03-30', 'TRSFR', 'IN83588',     12  , 12.45 ,     149.4 ) --IN, UnitCost is fixed


SELECT
    *,
    (SELECT SUM(Total) FROM @SampleTable S2 WHERE S2.Date < S1.Date AND S2.TransId LIKE 'IN%' AND S1.TransId LIKE 'OUT%') AS SumOutTransaction,
    (SELECT SUM(Qty) FROM @SampleTable S2 WHERE S2.Date < S1.Date AND S2.TransId LIKE 'IN%' AND S1.TransId LIKE 'OUT%') AS SumQtyTransaction,
    CASE
        WHEN S1.TransId LIKE 'OUT%' THEN
                                        (
                                            (SELECT SUM(Total) FROM @SampleTable S2 WHERE S2.Date < S1.Date AND S2.TransId LIKE 'IN%' AND S1.TransId LIKE 'OUT%')
                                            /
                                            (SELECT SUM(Qty) FROM @SampleTable S2 WHERE S2.Date < S1.Date AND S2.TransId LIKE 'IN%' AND S1.TransId LIKE 'OUT%')
                                        )
        ELSE Total/Qty
    END AS CalculatedUnitCost
FROM @SampleTable S1

Кроме этого, могут быть и другие, более оптимизированные варианты.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...