Расчет рассчитываемого поля в Vertica - PullRequest
1 голос
/ 05 августа 2020

У меня есть список записей, из которых мне нужно вычислить новое поле - я назову его «вычислением». Каждая строка зависит от количества предыдущих строк. Предоставляется первый индекс каждого поля «вычисления» идентификатора. Ниже приведен снимок экрана из Excel, показывающий то, что я пытаюсь сделать, но для миллионов записей, разделенных по ID

скриншот Excel, показывающий, что я хочу сделать

Мой запрос ниже не работает, так как расчет еще не существует

select ID, transaction, transaction-lag(calculation) over (partition by ID) as calculation from db

Возможно ли это в Vertica?

Ответы [ 2 ]

1 голос
/ 05 августа 2020

Ваши результаты зависят от порядка данных. Однако таблицы SQL представляют неупорядоченные наборы. Если я предполагаю, что у вас есть столбец, определяющий порядок, вам нужно что-то вроде этого:

select t.*,
       (first_value(calculation) over (partition by id order by <ordering col>) -
        sum(transaction) over (partition by id order by <ordering col>)
       ) as calculation
from t
0 голосов
/ 05 августа 2020

В конце концов, мне нужно это отредактировать. Я пробовал подход @Gordon Linoff, но безрезультатно, с примерами данных, которые я привожу в этом посте.

Я бы использовал функцию LAG() OLAP. Я также использую предложение Vertica named window для удобства чтения (WINDOW w AS ()).

В дополнение к этому: ваш лист Excel выполняет итерационные вычисления. Ваш C4 рассчитывается из B4 - C3, а C3 вычисляется, в свою очередь, как вы показываете, как B3 - C2. Итак, все, что я могу сделать, это вложить два очень похожих запроса:

В первом запросе из ваших входных данных, который я называю fillonce, мне удается вычислить C3, как IFNULL(calculation,transaction-LAG(calculation) OVER(w)) (используя именованное окно w), что означает: если calculation не равно нулю, используйте calculation, иначе вычтите calculation предыдущей строки (LAG()) из transaction этой строки.

Самый внешний запрос выбирает из fillonce и делает то же самое. Я добавил calc_org в качестве исходного номера расчета для справки.

Ваш ввод:

WITH
-- your input enhanced by row_num and expected result ...
input(id,row_num,transaction,calculation,expected) AS (
          SELECT 123,1, 3.75,1.45,1.45
UNION ALL SELECT 123,2, 4.55,NULL,3.10
UNION ALL SELECT 123,3, 4.13,NULL,1.03
UNION ALL SELECT 456,1,12.3 ,3.22,3.22
UNION ALL SELECT 456,2, 2.22,NULL,-1
)

- Конец вашего ввода ...

- что Теперь следует первая итерация заполнения пропущенных значений

- обратите внимание на указанное предложение window - WINDOW w AS (....)

,
fillonce AS (
  SELECT 
    id
  , row_num
  , transaction
  , calculation AS calc_org
  ,
      FIRST_VALUE(calculation) OVER(w) 
    - SUM(transaction) OVER(w) 
    AS calculation
  , expected
  FROM input
  WINDOW w AS (PARTITION BY id ORDER BY row_num)
)                                                      

- которое вернется в fillonce:

id  | row_num | transaction | calc_org | calculation | expected 
----+---------+-------------+----------+-------------+----------
123 |       1 |        3.75 |     1.45 |        1.45 |     1.45
123 |       2 |        4.55 |     NULL |        3.10 |     3.10
123 |       3 |        4.13 |     NULL |        NULL |     1.03
456 |       1 |       12.30 |     3.22 |        3.22 |     3.22
456 |       2 |        2.22 |     NULL |       -1.00 |    -1.00

- и последний выбор, где я заполняю последнее значение, которое все еще равно NULL:

SELECT 
  id
, row_num
, transaction
, calculation AS calc_org
, IFNULL(calculation,transaction - LAG(calculation) OVER(w)) AS calculation
, expected
FROM fillonce
WINDOW w AS (PARTITION BY id ORDER BY row_num)
;

- которое, наконец, возвращает:

 id  | row_num | transaction | calc_org | calculation | expected
-----+---------+-------------+----------+-------------+---------
 123 |       1 |        3.75 |     1.45 |        1.45 |     1.45
 123 |       2 |        4.55 |     3.10 |        3.10 |     3.10
 123 |       3 |        4.13 |     NULL |        1.03 |     1.03
 456 |       1 |       12.30 |     3.22 |        3.22 |     3.22
 456 |       2 |        2.22 |    -1.00 |       -1.00 |    -1.00
...