我有这样的表:
您可以注意到serp_flag列中有许多值为null。我需要填补这些领域。它必须填充先前的非空值。所以,如果我的最后一个非null值是1,那么之后的所有空字段应该是1,除非出现非空字段。类似地,如果最后一个非空值为0,则之后的所有空字段应为0.此表具有数百万条记录。
错误:Invalid operation:This type of correlated subquery pattern is not supported yet;
使用PostgreSQL和redshift。
我的查询:
select event_id, domain_userid, collector_tstamp, se_category, se_action, se_label, se_property,
CASE WHEN serp_flag = 0 THEN 0
WHEN serp_flag = 1 THEN 1
WHEN serp_flag is null then (select serp_flag from (select t2.serp_flag,(t1.collector_tstamp - t2.collector_tstamp) as time_diff from temp.serp_funnel t2
where t1.domain_userid = t2.domain_userid and (t1.collector_tstamp - t2.collector_tstamp) >= 0 and t2.serp_flag is not null order by time_diff limit 1))
END
from temp.serp_funnel t1
limit 100;
这就是我的表(部分内容)看起来的样子
|------------|----------------|--------------|
|domainid |timestamp |serp_flag |
|------------|----------------|--------------|
|d1 |t1 |1 |
|------------|----------------|--------------|
|d1 |t2 |null |
|------------|----------------|--------------|
|d1 |t3 |null |
|------------|----------------|--------------|
|d1 |t4 |0 |
|------------|----------------|--------------|
|d1 |t5 |null |
|------------|----------------|--------------|
这就是我想要的
|------------|----------------|--------------|
|domainid |timestamp |serp_flag |
|------------|----------------|--------------|
|d1 |t1 |1 |
|------------|----------------|--------------|
|d1 |t2 |1 |
|------------|----------------|--------------|
|d1 |t3 |1 |
|------------|----------------|--------------|
|d1 |t4 |0 |
|------------|----------------|--------------|
|d1 |t5 |0 |
|------------|----------------|--------------|
此外,还为每个域用户分类时间戳。
答案 0 :(得分:0)
您想要lag()
选项ignore null
:
select t.*,
lag(serp_flag ignore nulls) over (partition by domainid order by timestamp)
from t;
但是,Postgres不支持(但是?)。然后,您可能会想:“嘿,让我们使用filter
”:
select t.*
lag(serp_flag) filter (where serp_flag is not null) over (partition by domainid order by timestamp
from t;
这也不起作用。所以,这是一个使用两个步骤的方法。首先是max()
上的timestamp
,然后max()
上的serp_flag
{/ 1}}:
select t.*, max(serp_flag) over (partition by domainid, grp)
from (select t.*,
max(case when serp_flag is not null then timestamp end) over (partition by domainid order by timestamp) as grp
from t
) t;
我不能轻易想到一步到位的方法。
我当然应该注意到,通过子查询或横向连接可以很容易地完成:
select t.*, tt.serp_code
from t left join lateral
(select t.*
from t tt
where tt.domainid = t.domainid and
tt.timestamp <= t.timestamp and
tt.serp_flag is not null
order by tt.timestamp desc
limit 1
) tt;
这应该具有良好的性能,索引在t(domainid, timestamp, serp_flag)
。