使用 Snowflake SQL 填充最新的非 null 值

Cau*_*der 7 sql snowflake-cloud-data-platform

这是我的值表

id    category   

A     Apple
A     NULL     
A     Apple
B     NULL      
B     Pear
B     Pear
B     Peach
B     NULL
B     NULL
C     NULL
C     NULL
C     Apple
Run Code Online (Sandbox Code Playgroud)

这就是我想要的桌子

id    category   

A     Apple
A     Apple     
A     Apple
B     NULL      
B     Pear
B     Pear
B     Peach
B     Peach
B     Peach
C     NULL
C     NULL
C     Apple
Run Code Online (Sandbox Code Playgroud)

这些是我想要应用的规则;

  • 如果category为空,则用最新的category(对于该id)填充它
  • 如果该 id 没有上述类别的值,则保留为 null

我们可以想象有第三列称为日期,这就是数据排序的依据

我尝试使用first_value(),但类别列为空

我在 Snowflake 实例上使用 SQL

Gor*_*off 15

你似乎想要lag(. . . ignore nulls)。只有一件事:SQL 表代表无序集(技术上是多重集)。您需要一列来指定顺序。

所以:

select t.*,
       coalesce(lag(category ignore nulls) over (partition by id order by <ordering col>) as imputed_category
from t;
Run Code Online (Sandbox Code Playgroud)

事实上,事实证明last_value()这样做不需要coalesce()

select t.*,
       last_value(category ignore nulls) over (partition by id order by <ordering col>) as imputed_category
from t;
Run Code Online (Sandbox Code Playgroud)

  • 这就是我的做法:`coalesce(category, last_value(categoryignore nulls) over (partition by id order by date rows between unbounded previous and current row))` (4认同)

小智 7

对于那些几年后发现的人来说,不确定如何选择不可重现的示例。

这是功能正常的 Snowflake SQL 代码,它大规模地显示了其他答案的问题(特别是,背对背空值!!)

问题具体指出:

如果category为空,则用最新的category(对于该id)填充它

last_value() 和first_value() 与prev_value() 不同(不幸的是不存在)。

SELECT
    column1 as token,
    column2 as hr, 
    column3 as price, 
    lag(column3) ignore nulls over (partition by column1 order by column2) as lag_price,
-- you want to coalesce itself and null removed lags!!
    coalesce(column3, lag(column3) IGNORE NULLS over (partition by column1 order by column2)) as correct_price,

-- commented out because it does not work, not enough arguments to coalesce!!
-- coalesce(lag(category ignore nulls) over (partition by id order by <ordering col>) as imputed_category,
-- coalesce(lag(column3 ignore nulls) over (partition by column1 order by column2) as imputed_price,

    LAST_VALUE(column3 IGNORE NULLS) OVER (PARTITION BY column1 ORDER BY column2) AS last_price
FROM VALUES
    ('usd', 1, 10), ('usd',2, NULL), ('usd',3, NULL), 
    ('usd',4, NULL), ('usd',5, 20),
    ('eth', 1, 20), ('eth', 2, 21), 
    ('eth', 3, NULL), ('eth', 4, 10), 
('eth', 5, NULL), ('eth', 6, NULL);

Run Code Online (Sandbox Code Playgroud)

请注意,CORRECT_PRICE 符合问题的定义,而 last_value() 只是偶然看起来正确,因为该数据是有限的。

图片包括: 根据询问者的要求返回最新的空值的查询