【问题标题】:Calculation off of a calculated field in Vertica计算 Vertica 中的计算字段
【发布时间】:2020-08-05 14:01:13
【问题描述】:

我有一个记录列表,我需要从中计算一个新字段 - 我将其称为“计算” 每行取决于前面的行号。提供了每个 ID 的“计算”字段的第一个索引。请参阅下面的 excel 屏幕截图,显示我正在尝试做的事情,但对于数百万条记录,按 ID 分区

我下面的查询中断了,因为计算还不存在

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

这在 Vertica 中可行吗?

【问题讨论】:

  • 您的结果取决于行的顺序。哪一列指定了该排序?

标签: sql vertica


【解决方案1】:

您的结果取决于数据的顺序。但是,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

【讨论】:

  • 谢谢 - 是的,我有一个 row_num 列,抱歉我应该指定。您的解决方案会有所帮助,但计算并非全部基于第一个值,而是前一个值。所以在我的 excel 屏幕截图中,单元格 C4 将是 B4-C3。还有办法计算吗?
  • @tnerbusas 。 . .它们是查看同一计算的两种方式。累积总和做你想做的事。
【解决方案2】:

毕竟,我需要编辑这个。 我尝试了@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,否则从本行的transaction 中减去前一行的calculation (LAG())。

最外面的查询从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 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

【讨论】:

    猜你喜欢
    • 2012-10-11
    • 2022-08-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-07-19
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多