将 FIRST_VALUE 与基于另一列的条件一起使用

Posted

技术标签:

【中文标题】将 FIRST_VALUE 与基于另一列的条件一起使用【英文标题】:Using FIRST_VALUE with condition based on another column 【发布时间】:2020-10-19 11:20:38 【问题描述】:

我将 Snowflake 作为我们的数据仓库,但我的问题与任何支持窗口函数(如 FIRST_VALUE、LAST_VALUe、LEAD、LAG)的 SQL 方言有关。

我有一张桌子如下。 Sample Table

我想要创建另一个列,假设 PreferredCurrencyCurrent 基本上应该是来自记录的 PreferredCurrency 的最新值 EventName = AccountCreated 或 AccountUpdatedEvent2

所以,结果应该是这样的

Desired Result

我曾尝试使用窗口函数 FIRST_VALUE、LEAD/LAG,但未能通过检查 EventName 的附加条件来正确处理。

【问题讨论】:

【参考方案1】:

我认为 ANSI 标准的方式是

FIRST_VALUE(PreferredCurrency) 
    FILTER(WHERE EventName IN ('AccountCreated', 'AccountUpdatedEvent2')) 
    OVER(PARTITION BY AccountID ORDER BY EventCreated DESC)

但是,我不知道任何可以实际使用的 DBMS。我认为 Postgres 可能是最接近的,但 FILTER 子句尚未针对非聚合窗口函数实现。现在,我认为您将不得不使用一个相关的子查询:

SELECT *, 
        (   SELECT PreferredCurrency 
            FROM    T AS T2 
            WHERE   T2.AccountID = T.AccountID 
            AND     T2.EventName IN ('AccountCreated', 'AccountUpdatedEvent2') 
            AND     T2.EventCreated <= T.EventCreated 
            ORDER BY T2.EventCreated DESC 
            FETCH FIRST 1 ROWS ONLY -- or your DBMS Equivalent
        ) AS PreferredCurrencyCurrent
FROM    T
ORDER BY AccountKey DESC;

Example on DB<>Fiddle

【讨论】:

谢谢@GarethD。问题是我还有 20 个这样的列,相关子查询可能是性能瓶颈,而且我们的 DW Snowflake 不完全支持相关子查询:(

以上是关于将 FIRST_VALUE 与基于另一列的条件一起使用的主要内容,如果未能解决你的问题,请参考以下文章

根据另一列的先前值填充一列

有没有办法将所有 obs 条件保持在另一列的 top_n 值上

如何根据另一列的条件查询同一列两次?

Groupby 一列并计算另一列的条件?

如何将一列的列值组合到 MySQL 中的另一列中?

基于另一列的滞后窗口函数