2016-09-25 77 views
1

我有表是这样的:相关子查询模式不支持错误

Table here

您可以注意到有在serp_flag列空多值。我需要填补这些领域。它必须填充以前的非空值。所以,如果我的最后一个非空值是1,那么之后的所有空字段应该是1,除非非空字段出现。同样,如果最后一个非null值为0,那么之后的所有空字段都应为0.此表具有数百万条记录。

错误:Invalid operation:This type of correlated subquery pattern is not supported yet;

使用PostgreSQL和红移。

我的查询:

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

http://meta.stackoverflow.com/questions/285551/why-may-i-not-upload-images-of-code-on-so-when-asking-a-question/285557#285557 –

回答

0

你想要的是lag()ignore null s选项:

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; 

这也不行。所以,这是一个使用两个步骤的方法。首先对timestamp然后max()在一个max()serp_flag

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)指数不俗的表现。

+0

@ Gordan Linoff 我在'ORDER BY子句中得到聚合窗口函数需要一个框架子句错误'时增加了'无界前接和当前行之间的行'。现在,查询工作正常,除了两个事件的collector_tstamp相等的地方 –

+0

@KumarVivek。 。 。更新的Postgres版本不需要窗口子句。此外,您可以通过包含主键来区分排序来处理相等情况。 –

+0

@Gordan。感谢您的宝贵建议和对查询的帮助。将使用主键来区分排序。 –