Esper學習之九:EPL語法(五)
轉載請註明出處:http://blog.csdn.net/luonanqin
暫停更新三個多月,轉眼間就2014年了。年底相信都是大家最忙碌的時候,我也不例外,以至於真的是沒騰出手來繼續更新,好在年初這段時間可以休息一陣了,所以趕著這段時間空閒就多寫點吧。本來想先寫view,pattern這些常用的內容以滿足大部分人的需求,但是考慮到這些章節有涉及到前面章節的知識,所以我覺得基礎還是要學的,不能還沒學會走就想跑,否則可能會摔得很慘哦。
本篇的內容主要包括了Subquery(也就是子查詢)和Join,內容不少,但是不難,基本上和sql差不太多。
1.Subquery
EPL裡的Subquery和sql的類似,是否比sql的用法更多我不得而知,畢竟本人是sql菜鳥,只在where語句裡用過子查詢。廢話不多說,先上幾個Subquer的簡單用法:
子查詢結果作為外部事件的屬性
- select assetId, (select zone from ZoneClosed.std:lastevent()) as lastClosed from RFIDEvent
子查詢關聯外部事件的屬性
- select * from RfidEvent as RFID where 'Dock 1' = (select name from Zones.std:unique(zoneId) where zoneId = RFID.zoneId)
-
select zoneId, (select name from Zones.std:unique(zoneId) where zoneId = RFID.zoneId) as name from RFIDEvent
子查詢內部事件作為外部事件的屬性
- select (select * from MarketData.std:lastevent()) as md from SuperMarket
每進入一個SuperMarket事件就返回最新的MarketData事件作為屬性返回,別名為md
子查詢中應用聚合函式
- select * from MarketData where price > (select max(price) from MarketData(symbol='GOOG').std:lastevent())
- select * from OrderEvent oe where qty > (select sum(qty) from OrderEvent.win:time(1 hour) pd where pd.client = oe.client)
Filter中使用子查詢
- select * from BarData(ticker='MSFT', closePrice < (select movAgv from SMA20Stream(ticker='MSFT').std:lastevent()))
Pattern中使用子查詢
- select * from pattern [
- a=A -> b=B(bvalue = (select d_val from DNamedWindow as d where d.d_id = b.b_id and d.d_id = a.a_id))
- ]
pattern的含義可先不深究,這裡只要知道子查詢可以用在pattern中就行了。
Expression中使用子查詢(什麼是Expression?請看《Esper學習之五:EPL語法(一)》的第八點)
- expression subq {
- (select max(quantity) as maxq, min(quantity) as minq from OrderEvent.win:time(1 min))
- }
- select (quantity - minq) / (subq().maxq - subq().minq) as prorated from OrderEvent
以上就是子查詢的幾種簡單用法,不過有幾點注意事項是要各位悉知的:
1.子查詢的返回必須使用data window或者view來進行限制,控制子查詢使用的事件數(data window和view相當於具有某種功能性的事件集合)
2.子查詢語句只能由select子句,from子句以及where子句組成,其他的均不支援,比如group by,limit等
3.沒有關聯外部事件的子查詢語句也可以使用聚合函式
4.子查詢語句中的select子句必須對所有屬性使用聚合函式
5.在使用子查詢時,如果子查詢的事件和外部事件型別一樣,則事件到來時,先經過子查詢語句的處理,然後再經過外部語句的處理。如果包含了多個子查詢語句,則事件的處理順序規則較為複雜,本人暫時沒做研究。
針對第4點可能說得有些不明白,特此舉例說明下:
- class Apple {
- privateint price;
- privateint size;
- publicvoid setPrice(int price) {
- this.price = price;
- }
- publicvoid setSize(int size) {
- this.size = size;
- }
- publicint getPrice() {
- return price;
- }
- publicint getSize() {
- return size;
- }
- }
- class Fruit {
- }
- publicclass Test {
- publicstaticvoid main(String[] args) throws InterruptedException {
- EPServiceProvider epService = EPServiceProviderManager.getDefaultProvider();
- EPAdministrator admin = epService.getEPAdministrator();
- String epl1 = "select (select sum(price), sum(size) from " + Apple.class.getName() + ".std:lastevent()) from " + Fruit.class.getName();
- /*
- * 當然,對不同的屬性使用不同的聚合函式也是可以的
- */
- // String epl1 = "select (select sum(price), avg(size) from " + Apple.class.getName() + ".std:lastevent()) from " + Fruit.class.getName();
- /*
- * 注意:size沒有使用聚合函式,會導致建立epl失敗。文件中註明了“The properties of the subselect stream must all be within aggregation functions”.
- * 即子查詢中的select子句使用聚合函式時,所查詢的屬性都要使用聚合函式
- */
- // String epl1 = "select (select sum(price), size from " + Apple.class.getName() + ".std:lastevent()) from " + Fruit.class.getName();
- admin.createEPL(epl1);
- System.out.println("Create epl successfully!");
- }
- }
除了上面的語法外,有幾個關鍵字也是需要大家注意的。
exists
這個exists和exist可不一樣,雖說也是用在where子句中(不僅僅是where子句),但是exists前面是沒有什麼待比較屬性的。語法如下:
- exists (subquery)
- select * from Fruit as F where exists (select * from Apple.std:lastevent() where acount = F.fcount)
- select * from Fruit(exists (select * from Apple.win:keepall()))
1.exists後面的子查詢語句一定要用圓括號括起來,遺漏的話會報語法錯誤。
2.exists後面的子查詢語句只能返回單列值。什麼叫單列值?比如:Apple有price和size屬性,那麼select price和select size都是返回的單列(即一列),select price, size就是多列(即兩列)。如果subquery中返回的大於一列,則會報multi-column錯誤。謹記!
in / not in
用法和sql的一樣,具體語法就不說了,直接看例子吧:
- // 當前進入的Apple事件的aPrice存在於過去十秒內進入的Fruit的fPrice即可返回
- select * from Apple where aPrice in (select fPrice from Fruit.win:time(10 s))
注意:從語法上說in/not in前面是expression,並沒有規定只能是屬性。比如:Apple有aPrice和aSize兩個int屬性,則where子句可以寫成"aPrice+aSize in ....."(這裡只是舉例,不expression不表示任何意思)
any / some / all
除了用in或者not in判斷屬性值是否存在於子查詢結果中,還可以使用any/some/all並配合一些比較符號與子查詢結果進行比較。語法如下:
- expression operator any/some/all (subquery)
- // operator包含:>=, !=, <>, <, <=, >, >=
- // 如果當前Apple事件的aPrice小於前十個Fruit中的任何一個fPrice,則返回此事件
- select * from Apple where aPrice < any (select fPrice from Fruit.win:length(10))
- // 如果當前Apple事件的aPrice小於前十個Fruit中的所有fPrice,則返回此事件
- select * from Apple where aPrice < all (select fPrice from Fruit.win:length(10))
some和any同義,所以用法也相同。既然一樣為什麼又要弄這麼個關鍵字,我也沒搞懂。。。
子查詢返回多列資料
子查詢可以返回單列資料,也可以返回多列資料。用法很簡單,只需要“."(點)就能找到每列的資料了。示例如下:
- select *,
- (select bid, offer from MarketData.std:unique(symbol) as md where md.symbol = oe.symbol) as bidoffer
- from OrderEvent oe
2.Join
Join在sql裡是很常見的查詢方法,EPL也同樣支援,並且包含了full outer join / left outer join / right outer join / inner join等。和sql基本無差別。
inner join
在沒有任何關鍵字的修飾下,即為預設join方式,也就是inner join。必須等到所有join的事件都到了才可能輸出,因為要是有where關聯兩個事件,得滿足where條件了才能輸出。例如:
- select * from Orange.std:lastevent(), Banana.std:lastevent()
full outer join
上面看到的預設join方式是要求所有join的事件都必須到達引擎才會輸出,並且join的事件之間通過where子句設定了條件判斷,還得到達的兩個事件滿足條件了才能輸出,而full outer join正好解決了這個問題,不管哪個事件到達,不管是否符合條件,都會輸出。例如:
- select * from Orange.std:lastevent() as o full outer join Banana.std:lastevent() as b on o.price = b.price
a.當只有Orange事件到達,沒有滿足join條件,會輸出Orange事件,且Banana事件為null。
b.當只有Banana事件到達,沒有滿足join條件,會輸出Banana事件,且Orange事件為null。
c.當兩個事件都到達了,且沒有滿足join條件,即price不相等,則a,b情況各出現一次。
d.當兩個事件都到達了,且滿足join條件,即price相等,即可輸出滿足條件的事件。
所以說不管什麼情況下,當前進入的事件都會輸出,至於join的那個事件,滿足即輸出事件,不滿足即輸出null。
left outer join
full outer join輸出了所進入的所有事件,不滿足join條件的就輸出null,而left outer join則規定關鍵字左邊的事件可以即刻輸出,而關鍵字右邊的事件必須滿足join條件才可輸出。示例如下:
- select * from Pink.std:lastevent() as pi left outer join Pear.std:lastevent() as pe on pi.price = pe.price
right outer join
和left outer join相反,在關鍵字右邊的事件不受join條件約束,而左邊的事件必須滿足join條件才可輸出。具體例子我就不舉了,大家可以寫兩個句子試試。
此外,在使用以上4種join的時候,可以多種join混用。比如:
- select * from Apple.std:lastevent() as a
- left outer join Banana.std:lastevent() as b on a.price = b.price
- full outer join Orange.std:lastevent() as o on o.price = a.price
- // a,b分別是兩個事件的別名
-
相關推薦
Esper學習之九:EPL語法(五)
轉載請註明出處:http://blog.csdn.net/luonanqin 暫停更新三個多月,轉眼間就2014年了。年底相信都是大家最忙碌的時候,我也不例外,以至於真的是沒騰出手來繼續更新,好在年初這段時間可以休息一陣了,所以趕著這段
Esper學習之六:EPL語法(二)
轉載請註明出處:http://blog.csdn.net/luonanqin 中秋三天,說閒也不閒,調調工作的程式碼,倒還解決不少問題。不過也是因為最近工作忙的緣故,Esper被我冷落不少日子了,趁著今天最後一天,趕緊寫一篇出來。 從
Esper學習之十:EPL語法(六)
轉載請註明出處:http://blog.csdn.net/luonanqin 2014是新的一年,正好也是本人的本命年。既然是本命年,看來今年也是本人興旺之年了。。。開了個小玩笑,同時也祝各位同行今年少調bug多漲工資,這才是最實際的。
Esper學習筆記四:EPL語法(2)
1.select 查詢所有屬性或特定屬性 EPL的select和SQL的select很相近,SQL用*表示查詢表的所有欄位,而EPL用*表示查詢事件流的所有屬性值。SQL查詢某個欄位名,直接在select後跟欄位名就ok,EPL也是將要查詢的屬性名放在select之後。若查多個屬
Esper學習筆記三:EPL語法(1)
1.EPL語法簡介 EPL全稱Event Processing Language,是一種類似SQL的語言,包含了SELECT, FROM, WHERE, GROUP BY, HAVING 和 ORDER BY子句,同時用事件流代替了table作為資料來源,並且能像SQL那樣join,fil
Esper學習之十一:EPL語法(七)
轉載請註明出處:http://blog.csdn.net/luonanqin 元宵過後回公司上班,換了個部門,換了個領導,做的事也換了,不過Esper還是會繼續搞,所以部落格也會慢慢寫的,大家別急。^_^ 上一篇說到了EPL如何訪問關係型資料
Esper學習筆記五:EPL語法(3)
1.Aggregation 類似於SQL中的聚合函式,EPL中聚合函式格式如下: aggregate_function([all|distinct] expression) aggregate_function就是聚合函式的名字,比如avg,sum等。expression通常是事件
在Ubuntu上學習OpenStack之九:網絡(計算)節點上網絡補充配置
分享 ini onf stack -a ubunt con openstac bubuko (註意:前面已經為計算+網絡節點配置了兩塊網卡eth0和eth1) v 執行如下命令: sudo ovs-vsctl add-br br-eth1 sudo ovs-vsctl ad
WebRTC學習之九:攝像頭的捕捉和顯示
分享 註意 conn con wid pre rac art 升級版本 較新的WebRTC源代碼中已經沒有了與VoiceEngine結構相應的VidoeEngine了,取而代之的是MeidaEngine。MediaEngine包括了Medi
機器學習之支持向量機(三):核函數和KKT條件的理解
麻煩 ron 現在 調整 所有 核函數 多項式 err ges 註:關於支持向量機系列文章是借鑒大神的神作,加以自己的理解寫成的;若對原作者有損請告知,我會及時處理。轉載請標明來源。 序: 我在支持向量機系列中主要講支持向量機的公式推導,第一部分講到推出拉格朗日對偶函數的對
機器學習之支持向量機(一):支持向量機的公式推導
根據 監督式 art 通用 利用 哪些 這就是 在線 方法 註:關於支持向量機系列文章是借鑒大神的神作,加以自己的理解寫成的;若對原作者有損請告知,我會及時處理。轉載請標明來源。 序: 我在支持向量機系列中主要講支持向量機的公式推導,第一部分講到推出拉格朗日對偶函數的對偶因
C++系統學習之九:順序容器
元素在順序容器中的順序與其加入容器時的位置相對應。關聯容器中元素的位置由元素相關聯的關鍵字值決定。所有容器類都共享公共的介面,不同容器按不同方式對其進行擴充套件。 一個容器就是一些特定型別物件的集合。順序容器為程式設計師提供了控制元素儲存和訪問順序的能力。 1. 順序容器概述 容器的兩種效能: 向容
Keras學習之3:迴歸問題(boston_housing資料為例)
本實驗使用boston_housing資料集對房價資料進行迴歸分析,資料來自1970年代,波斯頓周邊地區的房價,是用於機器學習的經典資料集。該資料集很小,共計506條資料,分為404個訓練樣本和102個測試樣本,因此需要採用K-Fold,這裡取K=4。每條資料包含1
深度學習之正則化系列(2):資料集增強(資料增廣)
讓機器學習模型泛化得更好的最好辦法是使用更多的資料進行訓練。當然,在實踐中,我們擁有的資料量是很有限的。解決這個問題的一種方法是建立假資料並新增到訓練集中。對於一些機器學習任務,建立新的假資料相當簡單。對分類來說這種方法是最簡單的。分類器需要一個複雜的高維輸入
強化學習之三:雙臂賭博機(Two-armed Bandit)
本文是對Arthur Juliani在Medium平臺釋出的強化學習系列教程的個人中文翻譯,該翻譯是基於個人分享知識的目的進行的,歡迎交流!(This article is my personal translation for the tutorial wri
MQTT的學習之Mosquitto發布-訂閱(2)
creat 訂閱模式 pub 測試 方法 ssa clientm art ble 在《MQTT的學習之Mosquitto安裝&使用(1)》一文末尾,我已經模擬了發布-訂閱模式,只是那時在服務器直接模擬的,並不是java代碼模擬的。下面貼出Java代碼 1、首先引入依
機器學習之SVM初解與淺析(一):最大距離
機器學習 svm 最大距離 2 / ||w|| 這段時間在看周誌華大佬的《機器學習》,在看書的過程中,有時候會搜搜其他人寫的文章,對比來講,周教授講的內容還是比較深刻的,但是前幾天看到SVM這一章的時候,感覺甚是晦澀啊,第一感覺就是比較抽象,特別是對於像本人這種I
機器學習之SVM初解與淺析(一):
機器學習 svm 最大距離 2 / ||w||sdsshngshan‘gccha 這段時間在看周誌華大佬的《機器學習》,在看書的過程中,有時候會搜搜其他人寫的文章,對比來講,周教授講的內容還是比較深刻的,但是前幾天看到SVM這一章的時候,感覺甚是晦澀啊,第一感覺就
java基礎知識學習--------之枚舉類型(1)
blog 枚舉類型 csdn 相同 名稱 枚舉類 java string pac 枚舉類型的概念: 1 /** 2 * 目的:枚舉類型 3 * @author chenyanlong 4 * 日期:2017/10/22 5 * 網址:http://blo
前端學習入門-angular2-Typescript基本語法(二)
moved subst 一個 super clas color 模式 值類型 tin 接口 接口的創建 interface labelValue{ label:string; } //創建函數對接口進行調用 labelObj是