Vertica有一种非常好的操作类型:Event-Based Window operations,它基本上可以让您识别事件发生的时间。 例如,每当给定的布尔表达式解析为true时,conditional_true_event将递增计数器。 我们大量使用这种方法。
我们正在考虑迁移到RedShift,但我们需要一个类似的功能。 RedShift有一些不错的window functions,但我找不到这个。
有什么方法可以使用RedShift来模拟这个功能吗?
答案 0 :(得分:5)
使用窗口函数编写CONDITIONAL_TRUE_EVENT()
非常容易。它只是一个带有条件(COUNT
)的CASE
:
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或派生表(或自联接):
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表示。如果在checked for changes列中有NULL
个值 - 并且您想要查看是否有上一个非空值而不仅仅是前一个值的更改 - 则重写将更加复杂。
编辑:据我了解Redshift的文档,当存在ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW
时,窗口聚合需要显式窗口框架(ORDER BY
)。因此,您可以/必须使用它(或者在这些情况下使用Vertica中的默认框架。它可以是上面的,也可以是RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW
)。