在 RedShift 中是否有替代 Vertica 的 conditional_true_event 的方法?

Is there any alternative to Vertica's conditional_true_event in RedShift?

Vertica 有一种非常好的操作类型:Event-Based Window operations,它基本上可以让您识别事件何时发生。 例如,每次给定的布尔表达式解析为真时,conditional_true_event 都会增加一个计数器。 我们大量使用这种方法。

我们正在考虑迁移到 RedShift,但我们需要类似的功能。 RedShift 有一些不错的 window functions,但我找不到这个。

有什么方法可以使用 RedShift 模拟此功能?

CONDITIONAL_TRUE_EVENT() 用 window 函数写起来相当容易。它只是一个带有条件 (CASE) 的 COUNT:

SELECT ts, symbol, bid,
       CONDITIONAL_TRUE_EVENT(bid > 10.6)  
           OVER (ORDER BY ts) AS oce
FROM Tickstore3 
ORDER BY ts ;

变为:

SELECT ts, symbol, bid,
       COUNT(CASE WHEN bid > 10.6 THEN 1 END)  
           OVER (ORDER BY ts
                 ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) 
          AS oce
FROM Tickstore3 
ORDER BY ts ;

CONDITIONAL_CHANGE_EVENT()比较复杂,因为需要用到之前的值。可以使用 LAG()SUM()COUNT()(或 ROW_NUMBER())来模拟它。但它需要我认为 CTE 或派生的 table (或自连接):

SELECT ts, symbol, bid,
       CONDITIONAL_CHANGE_EVENT(bid)  
           OVER (ORDER BY ts) AS cce
FROM Tickstore3 
ORDER BY ts ;

将变为:

WITH emu AS
  ( SELECT ts, symbol, bid,
           CASE WHEN bid <> LAG(bid) OVER (ORDER BY ts) 
               THEN 1 
           END AS change_bid
    FROM Tickstore3
  ) 
SELECT ts, symbol, bid,
       COUNT(change_bid) 
           OVER (ORDER BY ts
                 ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) 
         AS cce
FROM emu 
ORDER BY ts ;

我不知道这个 CONDITIONAL_CHANGE_EVENT() 函数如何处理空值。如果检查更改列中有 NULL 个值 - 并且您想查看上一个非空值是否有变化,而不仅仅是前一个 - 重写将更加复杂。


编辑: 据我了解 Redshift 的文档,window 聚合需要明确的 window 框架(ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW)是一个 ORDER BY。因此,您 can/have 使用它(或在这些情况下 Vertica 中的任何默认框架。它是上面的或 RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW)。