中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

淺解比 SQL 更好用的 SPL(二)

發布時間:2020-07-07 09:50:20 來源:網絡 閱讀:707 作者:raqsoft 欄目:大數據

從 SQL 到SPL基本查詢語法遷移 之多表操作

上一篇我們針對單表的情形了解了如何把數據計算從 SQL 查詢遷移到集算器,或者更準確地說,遷移到集算器所使用的SPL集算語言。這個遷移過程,既有相同的概念,也有不同的思路。

接下來,我們一起針對多表的情況看一下集算器和SPL語言是如何發揮更大的優勢的。

JOIN 連接兩個記錄

在前面的例子中,我們得到了每個雇員的銷售額,如果進一步還想知道每個雇員給出的最小折扣,那就又復雜了些。因為折扣信息在另一張訂單明細表里。急性子的朋友可能上來就要 JOIN 兩個表,然后再聚合兩個測度字段——這樣就算錯了!正確的做法應該是每個測度字段先按分組聚合出結果,之后再 JOIN。這是因為先 JOIN 的話可能導致結果中出現重復記錄。

按照這個思路寫出 SQL,并和集算器中的SPL代碼進行比較:

SQL

select t1.employeeId, salesAmount, lowestDiscount from (
select employeeId, sum(money) salesAmount from order
where orderDate>=’2012-01-01′ and orderDate<‘2012-02-01’
group by employeeId
having sum(money)>5000) t1
left join (
select employeeId, min(discount) lowestDiscount from order
join orderDetail on order.orderId=orderDetail.orderId
where orderDate>=’2012-01-01′ and orderDate<‘2012-02-01’
group by employeeId) t2
on t1.employeeId=t2.employeeId

集算器A
1=connect(“hsqlDB”)
2=A1.query(“select * from order”)
3=A2.select(orderDate>=date(“2012-01-01”) && orderDate<date(“2012-02-01”))
4=A3.group(employeeId;~.sum(money):salesAmount)
5=A4.select(salesAmount>5000)
6=A1.query(“select * from orderDetail”)
7=join(A3:order,orderId;A6:orderDetail,orderId)
8=A7.group(A7.order.employeeId:employeeId;~.min(orderDetail.discount):lowestDiscount)
9=join(A5:r1,employeeId;A8:r2,employeeId)
10=A9.new(r1.employeeId:employeeId,r1.salesAmount:salesAmount,r2.lowestDiscount:lowestDiscount)
11>A1.close()

A5 之前是我們做過的聚合符合條件的按雇員分組的銷售額;
A6 查出訂單明細表的所有數據;

A7 中的SPL用到了對應 SQL 的多表連接的新函數 join。join 函數把兩個表連接起來,這里它的參數的含義是:將 A3 序表起一個別名 order,A6 序表起一個別名 orderDetail,然后用兩個表各自的 orderId 作為關聯字段,觀察 A7 的結果如下:
淺解比 SQL 更好用的 SPL(二)

可以看到,join 后形成的序表有 order、orderDetail 兩個字段,兩個字段的值分別直接指向了兩個原始序表的記錄,這就是說字段的值可以是復雜數據類型(包括序表、序列類型),也可以嵌套多層結構的數據,這是 SQL 語法里不允許的,也是SPL的特色和優勢之一。

下圖比較形象地說明了這種結構(長方形表示序表、橢圓形表示記錄、三角形表示關聯字段):
淺解比 SQL 更好用的 SPL(二)

A8 直接用SPL中的 group 函數對這個復雜結構的序表進行分組聚合運算,獲得各個雇員曾經給出的最小折扣。

再需要注意的一點是 A3 序表被后面兩個不同的動作(A4、A7)都使用了一次,達到了中間結果復用的效果。這種方式對于越是復雜的計算,往往作用越大,可以起到類似“數據模塊化”的作用。

在 A9 中通過SPL的 join 函數把 A5(銷售額超過 5000)、A8(最小折扣)兩個序表連接起來;

最后,A10 使用 new 函數生成新的序表結構,而數據來自 A9 復雜結構記錄的不同層次位置。

A10 最終的結果如下:
淺解比 SQL 更好用的 SPL(二)

簡單回顧一下,對于最后這個比較復雜的 SQL,如果你是個 SQL 高手,可能會看出第二個子查詢里的 where 并不是必須的,之所以保留它,是因為有可能會縮小處理數據的范圍,從而提升一些性能。這也是 SQL 的另一個特點,一方面需要不喘氣的一句話把整個查詢表達出來,另一方面還需要同時考慮性能優化因素,甚至即便考慮到了優化方案,也不一定能輕松、自然地描述出來。

在上面的例子中,不難體會出集算器以及SPL對分步過程的重視,每一個步驟的結果都是可以隨時觀察的,而且前面步驟的結果也可以重復利用,同時執行步驟也可以被程序員自由定制。這些特點最直接的好處是降低了學習和編碼的難度,而更本質的是符合人的自然思維,為描述復雜計算奠定了基礎。

UNION 等合并兩個集合

SQL 中還有一類針對多個集合(表)的運算,就是常說的并、合、交、差(UNION、UNION ALL、INTERSECTION、MINUS),與之對應的,在SPL中表示為 &、|、^、\。

集合運算時常需要判斷一條記錄是否重復,在這個細節上,SQL 和SPL有一點區別。SPL里因為序表、記錄,以及字段的值都被看成是一個對象,所以在進行并集運算時,可以比對元素是否為同一個對象,而 SQL 的記錄是抽象的,不是一個實體對象,所以只能通過逐個比對兩條記錄的字段值來判斷是否重復。

我們來看一下實際的例子:

集算器AB
1=connect(“hsqlDB”)

2=A1.query(“select * from order”)

3=A2.select(orderId>10251 && orderId<10256)=A2.select(orderId>10254 && orderId<10258)
4=A3&B3=A3B3
5=A3^B3=A3\B3
6>A1.close()

A3 序表的結果:

淺解比 SQL 更好用的 SPL(二)

B3 序表的結果:

淺解比 SQL 更好用的 SPL(二)

A3&B3,去掉重復合并到一起,并集運算后得到 A4 序表的結果:

淺解比 SQL 更好用的 SPL(二)

A3|B3,保留重復合并到一起,合集運算后得到 B4 序表的結果:

淺解比 SQL 更好用的 SPL(二)

A3^B3,取 A3 和 B3 里相同的記錄,交集運算后得到 A5 序表的結果:

淺解比 SQL 更好用的 SPL(二)

A3\B3,A3 里去掉 B3 中存在的記錄,差集運算后得到 A5 序表的結果:

淺解比 SQL 更好用的 SPL(二)

其它常用語法

最后,再看兩個常用的 SQL 函數語法,我們來對比看一下SPL的實現。

CASE WHEN …

SQL 中的 case when … then … else … end,在SPL中用 if 函數,語法是if(條件, 真值, 假值),下面的例子是把 employeeId<5 的分為一組,剩余的分到另一組:

SQL
select (case when employeeId<5 then 1 else 2 end)  groupId, orderId from order
集算器A
1=connect(“hsqlDB”)
2=A1.query(“select * from order”)
3=A2.new(if(employeeId<5,1,2):groupId,orderId)
4>A1.close()

COALESCE(exp1,exp2…expn)

SPL中仍然用 if 函數,if(條件, 真值, 假值),下面這個例子把 1000 這個特殊的值賦值給為 null 的 employeeId。

SQL
select coalesce(employeeId,1000) employeeId,orderId from order
集算器A
1=connect(“hsqlDB”)
2=A1.query(“select * from order”)
3=A2.new(if(employeeId==null,1000,employeeId):employeeId,orderId)
4>A1.close()

集算器(SPL)≠SQL

看完上面這些例子,會給人一個感覺:集算器,或者其中的SPL代碼只是 SQL 的替代品,而常用的關系數據庫系統(RDBMS)本身已經是存儲能力(數據表)+ 計算能力 (SQL) 的綜合體了,還要這么一個外來的計算體系干嘛?

針對這個疑問,有兩個層面的答案。首先是數據層面,并非所有要計算的數據都在數據庫里。當你手邊有個文本、excel 或從一個網絡服務臨時得到一些數據想要計算,或者從大量終端采集上來的數據馬上要處理出結果……如果這些都不得不倒騰到數據庫里然后再計算,還真是有點太繞了,更何況還可能涉及到數據庫的安裝部署,或者權限控制等瑣碎而現實的問題。

其次是計算層面,對于很多復雜的計算過程,SQL 因為天生缺陷無法做到開發高效、維護高效、執行效高。這也是我們這篇文章最想說明的地方,SQL 的計算主要還是面向查詢,而這些對“高效”的追求,面向的是更廣泛的數據計算,這正是集算器和SPL語言所要重點改善的。

正因為有了這兩個層面的原因,集算器和SPL語言已經可以獨立于各種數據存儲形式,在“存儲”和“應用”之間,作為一個功能完整、形式靈活、部署方便的“數據計算中間件”而存在。這方面的內容,我們會在后面的章節做更多的介紹和探討。

這里,我們只是先簡單看一下集算器和SPL語言如何基于文本、Excel 等數據源進行計算。事實上,前面這些例子中的計算步驟完全不用改寫,只需要改變加載數據那一句就可以了。也就是把:

=A1.query(“select * from order”)

改為下列任意方式之一:

=file(“d:/data/order.txt”).import@t()// 從文本文件加載數據表

=file(“d:/data/orderDetail.xls”).importxls@t()// 從 excel 加載數據表

=httpfile(“ http:/ /127.0.0.1/service ”,” param1=value1&param2=value2″) // 從 http server 加載數據表

……

很明顯,通過這種簡單明了的數據加載方式,可以將各種數據源的數據形成統一的“序表”,從而在一個計算過程里可以輕松混合使用。換句話說,不必為了計算能力而要求必須統一存儲方式。同樣的,在集算器和SPL的環境中,計算結果的存儲,也和加載數據一樣方便,也是多樣化的,可以由程序員自由選擇。


向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

香港| 夹江县| 卢湾区| 古丈县| 红原县| 临城县| 江山市| 博爱县| 富平县| 通河县| 错那县| 安化县| 江永县| 灌阳县| 西昌市| 九寨沟县| 平安县| 兴义市| 永平县| 郯城县| 泸溪县| 延津县| 娱乐| 桐梓县| 崇仁县| 农安县| 通道| 遂平县| 关岭| 达州市| 枣阳市| 灌南县| 广东省| 应用必备| 罗平县| 桓台县| 建昌县| 岢岚县| 南乐县| 威远县| 昭觉县|