一個寫 SQL 的神器

如果你經常需要寫大量的 SQL腳本 來進行數(shù)據分析工作闺魏,那你可能值得擁有這款神器:

https://github.com/taojy123/sqlx

SQLx 意為 SQL Extension史辙,強大的 SQL 語法拓展橙困,目標是打造 "易讀易寫 方便維護" 的 SQL 腳本。

應用場景

假設有一張商品價目表(product)漂彤,每天價格變動的商品都會更新報價。

例如,蘋果的最新價格為 10 元, 因為蘋果最新的一次報價是在 20191211, 當時價格為 10 元洞渔。

name(商品名稱) price(價格) date(報價日期)
蘋果 15 20191208
香蕉 18 20191208
橘子 12 20191208
香蕉 16 20191209
橘子 11 20191209
蘋果 11 20191210
橘子 13 20191210
蘋果 10 20191211
香蕉 22 20191211
橘子 14 20191212

現(xiàn)在要求通過 sql 統(tǒng)計出 20191212 這天的平均價格 比 20191209 那天漲了多少 ?

正常情況下我們可能會寫出這樣的 sql

SELECT
    a1.avg_price AS `20191209 平均價格`,
    a2.avg_price AS `20191212 平均價格`,
    (a2.avg_price - a1.avg_price) AS `漲價金額`
FROM
    (
        -- 求出各類別 20191209 前最后一次報價的平均價格
        SELECT
            avg(product.price) AS avg_price
        FROM
            (
                -- 求出各商品在 20191209 前最后一次報價的日期
                SELECT
                    name,
                    max(date) AS max_date
                FROM
                    product
                WHERE
                    date <= '20191209'
                GROUP BY
                    name
            ) AS t1
        LEFT JOIN product
        ON t1.name = product.name AND t1.max_date = product.date
    ) AS a1
LEFT JOIN
    (
        -- 再求出各類別 20191212 前最后一次報價的平均價格
        SELECT
            avg(product.price) AS avg_price
        FROM
            (
                -- 先求出各商品在 20191212 前最后一次報價的日期
                SELECT
                    name,
                    max(date) AS max_date
                FROM
                    product
                WHERE
                    date <= '20191212'
                GROUP BY
                    name
            ) AS t2
        LEFT JOIN product
        ON t2.name = product.name AND t2.max_date = product.date
    ) AS a2
ON true

得到統(tǒng)計結果如下:

20191209 平均價格 20191212 平均價格 漲價金額
14.0000 15.3333 1.3333

傳統(tǒng)做法雖然得到的結果是正確的,但同時暴露出以下問題:

  1. 子查詢多層嵌套缚态,代碼可讀性極低
  2. t1 t2 兩個子查詢內容基本一致磁椒,也就說我們要維護兩處相同的代碼
  3. a1 a2 兩個子查詢也基本一致,并且其中相同的注釋我們要寫兩遍玫芦,感覺太"蠢"了
  4. 這只是個很簡單的示例浆熔,在實際工作中,針對更復雜的統(tǒng)計需求桥帆,代碼的復雜度將會以指數(shù)形式遞增

下面看看如何使用 sqlx 來解決上述問題:

func product_max_date(day)
    -- 子查詢: 統(tǒng)計出各個商品在 {day} 前最后一次報價的日期
    (
        SELECT
            name,
            max(date) AS max_date
        FROM
            product
        WHERE
            date <= '{day}'
        GROUP BY
            name
    )
end

func date_avg_price(day):
    -- 子查詢: 統(tǒng)計出 {day} 這天各個類別的平均價格
    (
        SELECT
            avg(product.price) AS avg_price
        FROM
            {product_max_date($day)} AS t1
        LEFT JOIN product 
        ON t1.name = product.name AND t1.max_date = product.date
    )
end

SELECT
    a1.avg_price AS `20191209 平均價格`,
    a2.avg_price AS `20191212 平均價格`,
    (a2.avg_price - a1.avg_price) AS `漲價金額`
FROM
    {date_avg_price(20191209)} AS a1
LEFT JOIN 
    {date_avg_price(20191212)} AS a2
ON true

優(yōu)勢非常明顯:

  1. 核心代碼是一段短小的 SELECT医增,外加兩個子查詢的定義就搞定了,代碼邏輯清晰老虫,可讀性高
  2. a1 a2 使用類似 函數(shù) 的概念進行封裝叶骨,通過傳入不同的參數(shù)來生成不同的子查詢內容
  3. 相同邏輯的代碼片段只需要寫一遍,大大降低了代碼維護的工作量
  4. 使用 sqlx 提供的編譯工具或插件祈匙,可快速編譯成 sql 代碼忽刽,在數(shù)據庫中執(zhí)行結果一致

如何使用

先看一下 sqlx 的基本語法介紹,很簡單 5 分鐘就看明白學會了菊卷。

接下來就開始編寫你的 sqlx 腳本吧缔恳,保存文件時拓展名設為 .sqlx

然后下載 sqlx 的編譯工具,如果你使用 Windows 64位系統(tǒng) 可以直接下載 sqlx.exe 洁闰。雙擊運行歉甚,即可將當前目錄下的 sqlx 腳本文件一鍵編譯為 sql。

如果你使用 Sublime Text 編輯器扑眉,可以搜索下載 Sqlx Builder 插件來使用纸泄,更加方便赖钞。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市聘裁,隨后出現(xiàn)的幾起案子雪营,更是在濱河造成了極大的恐慌,老刑警劉巖衡便,帶你破解...
    沈念sama閱讀 221,548評論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件献起,死亡現(xiàn)場離奇詭異,居然都是意外死亡镣陕,警方通過查閱死者的電腦和手機谴餐,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,497評論 3 399
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來呆抑,“玉大人岂嗓,你說我怎么就攤上這事∪蛋” “怎么了厌殉?”我有些...
    開封第一講書人閱讀 167,990評論 0 360
  • 文/不壞的土叔 我叫張陵,是天一觀的道長侈咕。 經常有香客問我公罕,道長,這世上最難降的妖魔是什么乎完? 我笑而不...
    開封第一講書人閱讀 59,618評論 1 296
  • 正文 為了忘掉前任熏兄,我火速辦了婚禮,結果婚禮上树姨,老公的妹妹穿的比我還像新娘。我一直安慰自己桥状,他們只是感情好帽揪,可當我...
    茶點故事閱讀 68,618評論 6 397
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著辅斟,像睡著了一般转晰。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上士飒,一...
    開封第一講書人閱讀 52,246評論 1 308
  • 那天查邢,我揣著相機與錄音,去河邊找鬼酵幕。 笑死扰藕,一個胖子當著我的面吹牛,可吹牛的內容都是我干的芳撒。 我是一名探鬼主播邓深,決...
    沈念sama閱讀 40,819評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼未桥,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了芥备?” 一聲冷哼從身側響起冬耿,我...
    開封第一講書人閱讀 39,725評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎萌壳,沒想到半個月后亦镶,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經...
    沈念sama閱讀 46,268評論 1 320
  • 正文 獨居荒郊野嶺守林人離奇死亡袱瓮,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 38,356評論 3 340
  • 正文 我和宋清朗相戀三年缤骨,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片懂讯。...
    茶點故事閱讀 40,488評論 1 352
  • 序言:一個原本活蹦亂跳的男人離奇死亡荷憋,死狀恐怖,靈堂內的尸體忽然破棺而出褐望,到底是詐尸還是另有隱情勒庄,我是刑警寧澤,帶...
    沈念sama閱讀 36,181評論 5 350
  • 正文 年R本政府宣布瘫里,位于F島的核電站实蔽,受9級特大地震影響,放射性物質發(fā)生泄漏谨读。R本人自食惡果不足惜局装,卻給世界環(huán)境...
    茶點故事閱讀 41,862評論 3 333
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望劳殖。 院中可真熱鬧铐尚,春花似錦、人聲如沸哆姻。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,331評論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽矛缨。三九已至爹脾,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間箕昭,已是汗流浹背灵妨。 一陣腳步聲響...
    開封第一講書人閱讀 33,445評論 1 272
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留落竹,地道東北人泌霍。 一個月前我還...
    沈念sama閱讀 48,897評論 3 376
  • 正文 我出身青樓,卻偏偏與公主長得像筋量,于是被迫代替她去往敵國和親烹吵。 傳聞我的和親對象是個殘疾皇子碉熄,可洞房花燭夜當晚...
    茶點故事閱讀 45,500評論 2 359