Esper系列(六)子查询、Exists、In/not in、Any/Some、Join

子查询

// 子查询结果为外事件属性
String epsql = "select (select name from orderEvent.std:lastevent()) as result from orderEvent ";

注意:orderEvent.std:lastevent(),用于控制每次查询只输出一个事件流.

// 子查询关联外事件属性
String epsql = "select bean as result from orderEvent as oe where '张100' = (select name from orderEvent.std:unique(name) where oe.name = name) ";

注意:orderEvent.std:unique(name)作用为输出没有重复的事件流.

 

子查询也可用于Pattern和Expression中.

例句:

// 创建子查询表达式---注意这里的小细节子查询必须用小括号括起来
String exSql = "create expression exesql {(select min(salary) as misal,max(salary) as mxsal from orderEvent.win:time(20 sec)) }";
epAdmin.createEPL(exSql);
       
// 查询最近20 s内最大和最小的salary
String epsql = "select exesql().misal as result1 ,exesql().mxsal as  result2 from orderEvent ";
  1. 子查询的返回必须使用data window或者view来进行限制,控制子查询使用的事件数(data window和view相当于具有某种功能性的事件集合);
  2. 子查询语句只能由select子句,from子句以及where子句组成.
  3. 没有关联外部事件的子查询语句也可以使用聚合函数.
  4. 子查询语句中的select子句中的属性有用到聚合函数时其它属性字段也必须使用聚合函数.
  5. 在使用子查询时,如果子查询的事件和外部事件类型一样,则事件到来时先经过子查询语句的处理,然后再经过外部语句的处理.

 

Exists

格式:

exists (subquery)

作用:判读subquery子查询是否有结果,有结果返回true,没结果返回false.

例句:

String epsql = "select name as result from orderEvent where exists(select * from orderBean.std:lastevent())";

注意:

Subquery子查询语句只能返回单列值或者是*,不然查询报Subquery multi-column的查询错误.

 

In/not in

与SQL用法类似.

例句:

String epsql = "select name as result from orderEvent where 111 in (select salary from orderEvent.win:length_batch(5))";

Any/some

格式:

expression operator any (subquery)
expression operator some (subquery)

作用:配合一些比较符号(>=, !=, <>, <, <=, >, >=)与子查询结果进行比较;

例句:

String epsql = "select name as result from orderEvent where 111 <= any (select salary from orderEvent.win:length_batch(5))";
 
String epsql = "select name as result from orderEvent where 111 >= all (select salary from orderEvent.win:length_batch(5))";

注意:

运行以上三个例句后的结果,刚开始让很费解(对调试代码不做说明),因为win:length_batch(5))对子查询与外部查询中的产生的效果不一样导致。
以以上应用场景为例:
外部查询事件缓存在之前的Context节中有详细说明;
子查询缓存更新可理解为每次积累到5个事件流才会更新子查询事件缓存,超过5个将重新积累计数,;
满足输出需要两个条件:

  • 子查询中缓存的事件个数需要5个.
  • 子查询中缓存的事件中存在salary值符合条件的;

Join

格式:

事件A  关键字(inner join、full outer join、left outer join、right outer join) 事件B  on  事件连接条件

Inner join

默认的join方式,必须等到所有的join事件都到才能输出.

例句:

String epsql = "select * from orderEvent.std:lastevent(),orderBean.std:lastevent() ";

注:std:lastevent()必须加,不然报Joins require that at least one view is specified for each stream的错误.

Full outer join

1、两个事件不同时到达:不管事件输出的条件是否满足,当有事件到达时就输出.
2、两个事件同时达到:当条件满足,输出满足条件的数据;当条件不满足,输出,两个事件各输出一次.

例句:

String epsql = "select * from orderEvent.std:lastevent() as oe full outer join orderBean.std:lastevent() as ob on oe.salary=ob.value";

left outer join

关键字左边的事件到达时,不管条件是否满足都会输出,关键字右边的事件只有在满足join条件时才可以输出.

例句:

String epsql = "select * from orderEvent.std:lastevent() as oe left outer join orderBean.std:lastevent() as ob on oe.salary=ob.value";

1、right outer join与left outer join功能相反,在事件连接过程中,前后两个事件先后到达时,前到达的会被单独执行,但执行后事件缓存与内存中,与后到的事件会再次一起执行;
2、std:lastevent()对事件的修饰有缓存的作用;
3、以上四种事件连接可以多种混合使用;

Unidirectional Join

关键字unidirectional作用于修饰需要连接的事件,使被修饰的事件在连接执行过程中不缓存(无状态).

例句:

String epsql = "select * from orderEvent as oe unidirectional full outer join orderBean.std:lastevent() as ob on oe.salary=ob.value";

1、在一个执行语句中unidirectional只能修饰一个事件;
2、使用了unidirectional修饰的事件流就不能再用data window或者view修饰了(它们之间是互斥);
3、用unidirectional修饰的事件流,不能通过esper的查询api查出来,因为该事件流是无状态的,不会暂存在引擎中;

原文地址:https://www.cnblogs.com/jianyuan/p/5000655.html