我正在尝试在Flink的数据集API中实现以下简单查询。
select
t1_value1
from
table1
where
t1_suppkey not in (
select
t2_suppkey
from
table2
)
所以我的想法是执行一个Left Outer Join(table1.leftOuterJoin(table2)...)然后删除我得到t1_suppkey和t2_suppkey值的所有行。
所以我尝试了这样:
output = table1
.leftOuterJoin(table2).where("t1_suppkey").equalTo("t2_suppkey")
.with((Table1 t1, Table2 t2) -> new Tuple2<>(t1.ps_suppkey, t2.s_suppkey))
.returns(new TypeHint <Tuple2<Integer, Integer>>() {});
但是,如果我这样做,它总是失败“java.lang.NullPointerException”,我不知道为什么。如果我使用普通的Join而不是Left Outer Join代码可以工作,但这不是我想要的。
我是否需要以不同方式实现Left Join,或者是否有更简单的方法来重写Dataset API中的“not in”语句?
答案 0 :(得分:0)
DataSet API的外连接也会为内部未找到连接记录的外部记录调用JoinFunction
。在这种情况下,the JoinFunction.join()
method is called with null
。
由于您使用的是LEFT OUTER JOIN,因此第二个参数Table2 t2
可以是null
。 NullPointerException
由t2.s_suppkey
引起。您需要检查t2 == null
,并且只有t2
才能访问{。}}。
您还可以使用FlatJoinFunction
参数实现NOT IN联接,Collector
参数只有t1
才会发出t2 == null
。
另一种选择是使用Flink的批处理SQL support,它支持您示例中的查询。
答案 1 :(得分:0)
output = table1
.leftOuterJoin(table2)
.where("t1_suppkey").equalTo("t2_suppkey")
.with((Table1 t1, Table2 t2, Collector<Tuple2<Integer, Integer>> c) -> {
if(t2 == null) {
c.collect(new Tuple2<>(t1.t1_suppkey, t1.t1_value1));
}
else {
//Do nothing.
}})