SQL Server Рассчитать накопленную сумму / условный промежуточный итог в зависимости от различных флагов - PullRequest
0 голосов
/ 30 мая 2018

У меня есть таблица в SQL Server с данными, похожими на этот пример.

ID  Flag    Art.No  Amount
1   U   A1000   -100
2   U   B2000   -5
3   V   B2000   900
4   U   B2000   -10
5   I   B2000   50
6   U   B2000   -20
7   U   A1000   -50
8   I   A1000   1000
9   V   A1000   3600
10  U   A1000   -500
11  U   A1000   -100
12  U   A1000   -2000
13  I   A1000   2000
14  U   A1000   -1000
15  I   C3000   10000
16  U   C3000   -4000
17  U   B2000   -5
18  U   B2000   -5
19  I   B2000   40
20  V   B2000   200
21  U   A1000   -500
22  U   B2000   -50
23  U   C3000   -1000

Я хочу рассчитать накопленное значение на основе транзакций.Моя проблема состоит в том, что таблица содержит 3 типа транзакций.

  1. Флаг U - Продажи
  2. Флаг I - Входящие товары
  3. Флаг V - Инвентаризация

Когда появляется флаг U и I, сумма представляет изменение. Когда появляется флаг V, сумма представляет общую сумму при проведении инвентаризации

Словами, я хочу найти последнюю V-транзакцию для каждой единицы Ст.Нет, а затем сложите или вычтите транзакции U и I, чтобы получить кумулятивную сумму для каждой строки.Если нет V-транзакции, просмотрите весь набор данных.

Я сделал примеры с ожидаемым результатом для каждого Art.No

A1000

ID  Flag    Art.No  Amount  A1000 Example
1   U   A1000   -100    
7   U   A1000   -50 
8   I   A1000   1000    
9   V   A1000   3600    3600
10  U   A1000   -500    3100
11  U   A1000   -100    3000
12  U   A1000   -2000   1000
13  I   A1000   2000    3000
14  U   A1000   -1000   2000
21  U   A1000   -500    1500

B2000

ID  Flag    Art.No  Amount  B2000 Example
2   U   B2000   -5  
3   V   B2000   900 
4   U   B2000   -10 
5   I   B2000   50  
6   U   B2000   -20 
17  U   B2000   -5  
18  U   B2000   -5  
19  I   B2000   40  
20  V   B2000   200 200
22  U   B2000   -50 150

C3000

ID  Flag    Art.No  Amount  C3000 Example
15  I   C3000   10000   10000
16  U   C3000   -4000   6000
23  U   C3000   -1000   5000

Редактировать: чтобы получить больше истории в наборе данных, было бы неплохо иметь значения до последней V-транзакции, такой как

B2000

ID  Flag    Art.No  Amount  B2000 Example
2   U   B2000   -5  150
3   V   B2000   900 140
4   U   B2000   -10 140
5   I   B2000   50  190
6   U   B2000   -20 170
17  U   B2000   -5  165
18  U   B2000   -5  160
19  I   B2000   40  200
20  V   B2000   200 200
22  U   B2000   -50 150

Где каждая транзакция I и U учитывается, а V-транзакции игнорируются.

1 Ответ

0 голосов
/ 30 мая 2018
with cte as
 (
   select *,
      -- find the latest 'V' ID per ArtNo
      max(case when Flag = 'V' then ID end) 
      over (partition by ArtNo) as Last_V_ID
   from myTable
 )
select *,
   -- cumulative sum, but ignore all rows before the latest 'V' ID
   -- includes rows when there's no 'V' ID for this ArtNo
   sum(case when ID < Last_V_ID then null else Amount end)
   over (partition by ArtNo
         order by ID
         rows unbounded preceding)
from cte
order by ArtNo, ID

См. Fiddle

Редактировать:

Чтобы включить данные до последней инвентаризации и игнорировать все предыдущие инвентаризации, вы можете использовать этот подход:

with cte as
 (
   select *,
      -- find the latest 'V' ID per ArtNo
      max(case when Flag = 'V' then ID end) 
      over (partition by ArtNo) as Last_V_ID
   from [dbo].[Warehouse]
 )
select *,
   -- cumulative sum, but ignore all rows before the latest 'V' ID
   -- includes rows when there's no 'V' ID for this ArtNo
   sum(case when ID < Last_V_ID then null else Amount end)
   over (partition by ArtNo
         order by ID
         rows unbounded preceding)
   -- calculate in-stock based on last 'V' ID, discarding all previous 'V' rows
  ,sum(case when (ID < Last_V_ID and Flag <> 'V')  then -Amount 
            when ID = Last_V_ID then Amount 
       end)
   over (partition by ArtNo
         order by ID 
         rows between 1 following and unbounded following)
from cte
order by ArtNo, ID

Оба вычисления являются взаимоисключающими, поэтому их легко объединить с помощью COALESCE.

См. Fiddle

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