Как передать значение предыдущей строки в текущую строку? - PullRequest
0 голосов
/ 12 октября 2018

Как передать результат предыдущей строки в вычисление текущей строки

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

формула:

  1. Средняя стоимость - это сумма стоимости транзакции
  2. Если Type - Sub, тогда Trx-стоимость равна стоимости
  3. Если Type - Red, тогда Trx-стоимость равнаЕдиница * (сумма предыдущей стоимости trx / сумма предыдущих единиц)
|  Row | Type | Unit | Cost | TrxCost  | Ave_cost |
|  1   |Sub   | 0.2  | 1000 |  1000    | 1000     |
|  2   |Sub   | 0.3  | 2500 |  2500    | 3500     |
|  3   |Sub   | 0.1  | 600  |  600     | 4100     |
|  4   |Red   |- 0.2 |-1100 | -1366.67 | 2733.33  |
|  5   |Sub   | 0.3  | 1000 |  1000    | 3733.33  |
|  6   |Red   | -0.6 | -600 | -3200    | 533.33   |

Обновление:

Заказ основан на номере строки.

Спасибо.

Ответы [ 3 ]

0 голосов
/ 12 октября 2018

Вы можете использовать Recursive CTE

WITH cte (row_num,
     type,
     unit,
     sum_of_unit,
     cost,
     trxcost,
     ave_cost
) AS (
     SELECT row_num,
            type,
            unit,
            unit AS sum_of_unit,
            cost,
            cost AS trxcost,
            cost AS ave_cost
     FROM t
     WHERE row_num IN (
          SELECT MIN(row_num)
          FROM t
     )
     UNION ALL
     SELECT t.row_num,
            t.type,
            t.unit,
            c.sum_of_unit + t.unit AS sum_of_unit,
            t.cost,
            CASE t.type
                 WHEN 'Sub'   THEN t.cost
                 WHEN 'Red'   THEN t.unit * ( c.ave_cost / c.sum_of_unit )
            END
       AS trxcost,
            c.ave_cost + CASE t.type
                 WHEN 'Sub'   THEN t.cost
                 WHEN 'Red'   THEN t.unit * ( c.ave_cost / c.sum_of_unit )
            END AS ave_cost
     FROM t
     JOIN cte c ON t.row_num = c.row_num + 1
)
SELECT * FROM cte

Dbfiddle Demo

0 голосов
/ 12 октября 2018

Вы можете сделать это в два прохода: один, чтобы получить theTrxCost, затем один, чтобы получить Ave_cost.

То, что вы называете "средним", это, кстати, промежуточная сумма;вы просто складываете значения.

Вам нужны оконные функции с предложениями ROWS BETWEEN.(В случае SUM(...) OVER (ORDER BY ...) это неявно BETWEEN UNBOUNDED PRECEDING AND CURRENT, однако).

select 
  id, type, unit, cost, round(trxcost, 2) as trxcost,
  round(sum(trxcost) over (order by id), 2) as ave_cost
from
(
  select 
    id, type, unit, cost,
    case 
      when type = 'Sub' then cost 
      else
        unit *
        sum(cost) over (order by id rows between unbounded preceding and 1 preceding) /
        sum(unit) over (order by id rows between unbounded preceding and 1 preceding)
    end as trxcost
  from mytable
)
order by id;

Я переименовал ваш row столбец id, потому что ROW является зарезервированным словом.

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

Rextester demo: https://rextester.com/ASXFY4323

0 голосов
/ 12 октября 2018

См. Функции окна SQL , которые позволяют получить доступ к значениям из других строк в наборе результатов.В вашем случае вам нужно будет сообщить нам еще несколько критериев того, когда прекратить искать и т. Д.Должна быть какая-то колонка, о которой вы нам не говорите.Если этот столбец (PartNumber?) Известен, вы можете просто сгруппировать и суммировать по нему.

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