Создать вычисляемое поле на основе предыдущих строк Oracle SQL - PullRequest
0 голосов
/ 10 июня 2019

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

В настоящее время у меня есть таблица, которая выглядит следующим образом:

| Group        | Part | Operation Type | Transaction Amount |
|--------------|------|----------------|--------------------|
| Concrete     | A    | STOCK          | 100                |
| Concrete     | A    | Buy            | 25                 |
| Concrete     | A    | Make           | -10                |
| Concrete     | A    | Make           | -10                |
| Concrete     | A    | Make           | -10                |
| Concrete     | A    | Make           | -10                |
| Concrete     | A    | Make           | -10                |
| Concrete     | B    | STOCK          | -10                |
| Concrete     | B    | Make           | -10                |
| Concrete     | B    | Make           | -10                |
| Concrete     | B    | Make           | -10                |
| Concrete     | B    | Make           | -10                |
| Concrete     | B    | Make           | 150                |
| Construction | C    | STOCK          | 10                 |
| Construction | C    | Make           | -1                 |
| Construction | C    | Make           | -1                 |
| Construction | C    | Make           | -1                 |
| Construction | C    | Make           | -1                 |
| Construction | D    | STOCK          | 5                  |
| Construction | D    | Make           | -5                 |

Таблицасначала упорядоченный по group, затем по part, а затем STOCK всегда отображается в качестве первого значения.Идея состоит в том, чтобы создать новый вычисляемый вручную столбец curr_inventory, который позволяет нам отслеживать текущий инвентарь и видеть, падает ли наш инвентарь для данной детали для данной группы ниже 0.

В идеале конечные результаты должны выглядеть следующим образом:

|     Group    | Part | Operation Type | Transaction Amount | New_Inventory_Column |
|:------------:|:----:|:--------------:|:------------------:|:--------------------:|
|   Concrete   |   A  |      STOCK     |         100        |          100         |
|   Concrete   |   A  |       Buy      |         25         |          125         |
|   Concrete   |   A  |      Make      |         -10        |          115         |
|   Concrete   |   A  |      Make      |         -10        |          105         |
|   Concrete   |   A  |      Make      |         -10        |          95          |
|   Concrete   |   A  |      Make      |         -10        |          85          |
|   Concrete   |   A  |      Make      |         -10        |          75          |
|   Concrete   |   B  |      STOCK     |         10         |          10          |
|   Concrete   |   B  |      Make      |         -10        |           0          |
|   Concrete   |   B  |      Make      |         -10        |          -10         |
|   Concrete   |   B  |      Make      |         -10        |          -20         |
|   Concrete   |   B  |      Make      |         -10        |          -30         |
|   Concrete   |   B  |      Make      |         150        |          120         |
| Construction |   C  |      STOCK     |         10         |          10          |
| Construction |   C  |      Make      |         -1         |           9          |
| Construction |   C  |      Make      |         -1         |           8          |
| Construction |   C  |      Make      |         -1         |           7          |
| Construction |   C  |      Make      |         -1         |           6          |
| Construction |   D  |      STOCK     |          5         |           5          |
| Construction |   D  |      Make      |         -5         |           0          |

Конечным результатом будет столбец, который начинается, когда номер детали изменился и тип операции STOCK, а затем начинает вычислять (используясумма сделки) текущая инвентаризация.Я не уверен, с чего начать SQL-запрос, который позволил бы это.Интуитивно понятно, что псевдокод будет выглядеть примерно так:

for each row in table:
    if operation_type == "stock":
        curr_inv = stock.value
    else:
        curr_inv = previous_curr_inv + transaction_amount

Однако я не уверен, как вообще начать писать SQL для этого.Обычно я пытаюсь опубликовать, с каким SQL я работаю, но я даже не знаю, с чего начать.Я просматривал различные посты в Интернете, на SO, включая посты , подобные , и , и , но я не мог понять, как выбранные ответы могутиспользовать в качестве решения.

Ответы [ 2 ]

1 голос
/ 11 июня 2019

Я использовал оконную функцию для вычисления промежуточного итога.

Я добавил столбец row_number в подзапрос.

Попробуйте это:

select t1."Group",t1."Part",t1."Operation Type", t1."Transaction Amount",
sum(t1."Transaction Amount") over (partition by t1."Group",t1."Part" order by t1.rownumber)
from (
select row_number() over (order by null) as rownumber, t.*
from test t ) t1

Результат теста:

DB <> Fiddle

0 голосов
/ 10 июня 2019

Таблицы SQL представляют неупорядоченные наборы.Чтобы навести порядок, нужна колонка с порядком.В приведенном ниже коде я буду использовать ? для этого столбца.

Тогда вам понадобится накопленная сумма:

select t.*,
       sum(case when operation_type in ('STOCK'),
                when operation_type in ('Make') then - amount
                when operation_type in ('Buy') then - amount
                else 0
           end) over (partition by group, part order by ?)
from t;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...