在 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
)。
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
)。