我想在最后一次满足该组的条件之后为每个组选择所有行。该related question的答案使用相关子查询。
就我而言,我将拥有数以百万计的类别和数以亿计的行。 是否有一种方法可以使用性能更高的查询获得相同的结果?
这里是一个例子。条件是条件列中最后一个0之后的所有行(每组)。
category | timestamp | condition
--------------------------------------
A | 1 | 0
A | 2 | 1
A | 3 | 0
A | 4 | 1
A | 5 | 1
B | 1 | 0
B | 2 | 1
B | 3 | 1
我想要实现的结果是
category | timestamp | condition
--------------------------------------
A | 4 | 1
A | 5 | 1
B | 2 | 1
B | 3 | 1
答案 0 :(得分:1)
如果要在最后一个0
之后输入所有内容,可以使用窗口函数:
select t.*
from (select t.*,
max(case when condition = 0 then timestamp end) over (partition by category) as max_timestamp_0
from t
) t
where timestamp > max_timestamp_0 or
max_timestamp_0 is null;
在(category, condition, timestamp)
上有一个索引,相关的子查询版本也可能执行得很好:
select t.*
from t
where t.timestamp > all (select t2.timestamp
from t t2
where t2.category = t.category and
t2.condition = 0
);
答案 1 :(得分:1)
您可能想尝试窗口功能:
select category, timestamp, condition
from (
select
t.*,
min(condition) over(partition by category order by timestamp desc) min_cond
from mytable t
) t
where min_cond = 1
带有min()
子句的窗口order by
计算同一condition
的当前行和后续行中category
的最小值:我们可以将其用作过滤器消除最近的行带有0
的行。
与相关子查询方法相比,使用窗口函数的好处是它减少了表上所需的扫描次数。当然,这种计算也需要一定的成本,因此您需要根据样本数据评估两种解决方案。