SQL複用告別拷貝黏貼!兄dei, 來看看

本文將介紹如何通過MLSQL將一條又長又複雜(子查詢,Join以及重複片段滿天飛)的SQL簡化成萌新都能看懂的SQL語句。

​案例來了

下面一條SQL是從網上隨便找的,大家可以看到,這條SQL結構上從結構上具備複雜化的潛質,子查詢,Join等用的不亦樂乎。然而和真實的業務場景裏的SQL複雜度比前來,這條SQL的複雜度簡直是孫子級別的。

如果我們仔細思考下,我們至少發現兩點:

  1. 這條SQL語句嵌套比較多,也就是裏面有不少子查詢以及join(union)查詢。無論對於計算機還是人,嵌套分支其實都不是友好的,對人而言加大了理解難度,對機器而言會影響流水線並行。
  2. SQL裏很多比較複雜的結構比如case when會重複的使用在同一條SQL語句的多個地方,你會驚訝的發現沒有辦法複用。

還有一點,數倉是有嚴格管理的,通常也有專業的團隊維護,這意味着你並不能隨心所欲在在數倉創建你經常用到的表。比如你經常會組合數倉中的A,B,C表得到一張表D,該表一般作爲子查詢使用。遺憾的是,你可能沒辦法很容易的去說服數倉團隊幫你持久化D表。不得已,你可能需要有個小本本記住這條SQL,然後需要用的時候複製拷貝黏貼進你的業務SQL(大部分情況會作爲子查詢)。

因爲當前大部分系統實現的SQL是以語句爲單位的,多條SQL要聯繫起來,需要將表落地,而這個成本是比較高昂的,所以大家儘可能將一個功能需求在一條SQL中來完成,這又反向導致SQL變得很複雜。

現在,我們來用MLSQL來簡化上面那條SQL。<u style="text-decoration: none; border-bottom: 1px dashed grey;">MLSQL</u> 是面向大數據和AI的一門語言,對SQL做了一定的增強,使得SQL更適用於腳本。

打平SQL,線性結構最符合大腦

首先,我們先把SQL展開,順序化。在MLSQL中做法很簡單,把子查詢都摘錄出來,然後在每個子查詢語句的最後用分號來表示一條語句結束了。

在MLSQL Console裏是這樣的:

這個腳本是可以直接運行的,只需點擊Run即可。

我們看到MLSQL允許你將一條條子查詢獨立出來,每條語句使用分號進行分割。其次,在後續語句中,你可以直接引用已經獨立出來的子查詢。進一步的,爲了保持語法上的一致,MLSQL要求所有Select語句都需要以as TableName結尾。通過打平SQL語句,使得單條SQL複雜度有了很大的降低。

將多條SQL語句拆開成多個文件

創建a.mlsql, b.mlsql, main.mlsql 三個腳本。

其中a.mlsql爲:

b.mlsql爲:

main.mlsql:

可以看到,MLSQL支持inlclude語法,允許你將某些腳本包含到另外一個腳本中。在MLSQL最後的結果是這樣:

這意味着,以後你要用a表,b表,你可以直接include對應的文件即可。

消除重複語句

我們發現下面兩句非常重複,基本上意味着你必然會進行拷貝黏貼。

通過MLSQL我們可以進一步消消樂:

這裏,我們通過set語法設置了一個模板,你會發現模板裏有幾個特殊的字符:

{0}

{1}

這個是參數佔位符,他們分別會被第一個參數和第二個參數替換。對於語句:

  ${template.get("selectTemplate","a","b")}

系統首先會找到模板selectTemplate,然後用a替換{0},用b替換所有{1},最後語句會被渲染成:

a.player AS player , a.lose AS totallose, b.win AS totalwin, (totallose+totalwin) AS total

set語法也可以單獨成一個文件,然後被其他語句引用。

最後成品:

可以看到,語句簡化了非常多,而且更加易於閱讀和複用,避免拷貝黏貼。

=========
歡迎大家關注我公衆號 【祝威廉】

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章