What is the difference between selection push down and predicate push down?
为什么只有当predicate 或者 selection 在agg函数的group by包含的col里面,才可以进行下推?
举个例子:
select COUNT(*) as name_count from t group by name having name = “Tony” and age > 20
像这种SQL,having中的2个filter name和age应该都可以进行下推而不影响结果?有没有一个例子去解释这个逻辑?
2 下面的聚合是不可以谓词下推的:
select count(*) as c from t1 where c == “10”
select a, count(b) as c from t1 group by a where c == “10″
这个其实是很好理解的,2 这种情况类似我们在 sql 里面写的 having 语句一样,是为了过滤分组聚合后的结果用的,如果把这个过滤下推,就相当于你把 count(*) 的别名 c 下推当成成了原始表中的 c字段,那么统计的结果就是错的, 而 1 的情况因为 a 字段在分组的字段里面, 这种经过 having 过滤后,其他 a 不为1 的分组肯定会被过滤掉, 所以 聚合后过滤 和 聚合前过滤,两者是等价的,可以谓词下推
如果 Aggregation 之上的 filter 中包含非 group by 的列,然后把这个 filter 推下了 Aggregation,那么这个时候这个 filter 会有可能过滤掉某个 Group 内部的行。
比如表 t 有 a b 两列,数据是(1, 2), (1, 3)。select * from (select a, count(*) from t group by a) t where a > 1 and b > 2
如果把 b > 2 下推的话,那么原本 a=1 的 group 在进入 Aggregate 时有两列,但是下推之后进入 Aggregate 的就只有一列了。导致结果出现了错误。
然后 selection push down 和 predicate push down 是不是在两个不同的地方看到的?原则上可以认为是一样的
select * from (select a, count(*) from t group by a) t where a > 1 and b > 2 这个例子应该想说a=1吧?我明白如果下推b>2这个filter会过滤掉一些行,导致进入count的时候会少一些,也会让里面的temporal result不同。但是这会影响整体的结果么?外层的filter b > 2 会根据哪个列进行比较呢?sub-query产生的table只有a 和count(*) 两列。