相关子查询模式不支持错误

时间:2016-09-25 15:07:21

标签: sql postgresql

我有这样的表:

Table here

您可以注意到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             |
|------------|----------------|--------------|

此外,还为每个域用户分类时间戳。

1 个答案:

答案 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)