1. 使SQL更易于閱讀的幾個(gè)小技巧

        共 3463字,需瀏覽 7分鐘

         ·

        2020-08-12 21:30

        點(diǎn)擊上方數(shù)據(jù)管道”,選擇“置頂星標(biāo)”公眾號(hào)

        干貨福利,第一時(shí)間送達(dá)


        無(wú)論是數(shù)倉(cāng)開(kāi)發(fā)還是數(shù)據(jù)分析,寫(xiě)一手好的SQL是一項(xiàng)基本的技能。毋庸置疑,編寫(xiě)性能較好的SQL是非常重要的,但是,SQL的可讀性同樣是不容小覷的。一個(gè)有著混亂格式的SQL腳本,往往需要花費(fèi)較長(zhǎng)的時(shí)間去弄清楚腳本的具體邏輯。如果你曾經(jīng)被祖?zhèn)鞯暮翢o(wú)章法的SQL腳本狂虐過(guò),你一定心有感觸。本文將分享幾個(gè)SQL格式的規(guī)范,當(dāng)然仁者見(jiàn)仁智者見(jiàn)智,其實(shí)沒(méi)有嚴(yán)格的標(biāo)準(zhǔn),如果有,那就是保證易于閱讀和易于維護(hù)。

        秦人不暇自哀,而后人哀之;后人哀之而不鑒之,亦使后人而復(fù)哀后人也

        大小寫(xiě)保持一致

        可以對(duì)SQL關(guān)鍵字使用不同的大小寫(xiě),但是要保持一致??纯催@個(gè):

        SELECT?customer_city,count(*)?from?dim_customer?WHERE?customerProvince?=?'上海'?Group?by?customer_city

        上面的SQL語(yǔ)句是不是很讓人抓狂,大小寫(xiě)混用,看起來(lái)很不規(guī)范??偨Y(jié)起來(lái),要注意下面幾點(diǎn):

        • SQL的關(guān)鍵字可以大寫(xiě),也可以小寫(xiě),但是不要大小寫(xiě)混用。上面的SQL查詢既有完全大寫(xiě),也有首字母大寫(xiě),更有小寫(xiě)??此剖遣痪行」?jié),但是萬(wàn)萬(wàn)使不得。
        • 由于大小寫(xiě)是混合的,因此很難區(qū)分小寫(xiě)的關(guān)鍵字實(shí)際上是關(guān)鍵字還是列。此外,閱讀也很煩人。
        • 字段命名要保持一致的風(fēng)格,上面的SQL與中customer_city是小寫(xiě)加下劃線,而customerProvince字段是駝峰命名法,這種不一致性顯然是不可取的。

        進(jìn)行一些規(guī)范之后,查詢應(yīng)如下所示:

        SELECT?customer_city,
        ???????count(*)
        FROM?dim_customer
        WHERE?customer_province?=?'上海'
        GROUP?BY?customer_city

        使用縮進(jìn)

        再來(lái)看看下面的一條查詢語(yǔ)句:

        SELECT?dp.region_name,count(*)?FROM?user_behavior_log?ubl?JOIN?dim_province?dp?ON?ubl.province?=?dp.province_name?WHERE?ubl.province?=?'上海市'?GROUP?BY?dp.region_name

        將上面的SQL語(yǔ)句格式化下面的形式:

        SELECT?dp.region_name,?count(*)
        FROM?user_behavior_log?ubl
        JOIN?dim_province?dp?ON?ubl.province?=?dp.province_name
        WHERE?ubl.province?=?'上海市'
        GROUP?BY?dp.region_name

        上面的格式化形式似乎清晰了很多,但是如果語(yǔ)句中包含了子查詢、多個(gè)JOIN以及窗口函數(shù)時(shí),同樣會(huì)顯得對(duì)閱讀不是很友好。

        再換一種格式化方式,如下:

        SELECT
        ????dp.region_name,?
        ????count(*)
        FROM?user_behavior_log?ubl
        ????JOIN?dim_province?dp?ON?ubl.province?=?dp.province_name
        WHERE?ubl.province?=?'上海市'
        GROUP?BY
        ????dp.region_name

        --?或者下面的形式
        SELECT
        ????dp.region_name?
        ????,count(*)
        FROM?user_behavior_log?ubl
        ????JOIN?dim_province?dp?ON?ubl.province?=?dp.province_name
        WHERE?ubl.province?=?'上海市'
        GROUP?BY
        ????dp.region_name

        尖叫提示:對(duì)于第二種形式,在SELECT字段中,從第二個(gè)字段開(kāi)始,每個(gè)字段前面添加一個(gè)逗號(hào),而不是每個(gè)字段后面使用逗號(hào)結(jié)尾。這種方式可以很方便地識(shí)別FROM前面是否存在逗號(hào),從而造成語(yǔ)法錯(cuò)誤。當(dāng)然,這個(gè)只是個(gè)人習(xí)慣問(wèn)題,并不是硬性的規(guī)定。

        另外上面的SQL語(yǔ)句使用了4個(gè)字符縮進(jìn),當(dāng)然也可以選擇2個(gè)字符縮進(jìn),這個(gè)也是個(gè)人習(xí)慣問(wèn)題。

        在group by 和order by之后使用字段的排列序號(hào)

        同樣,這種書(shū)寫(xiě)風(fēng)格也是個(gè)人的一種偏好,并不是一條硬性規(guī)定。應(yīng)該有很多的初學(xué)者對(duì)此種寫(xiě)法并不是很清楚。

        看下面的這條SQL:

        SELECT
        ????dp.region_name,?
        ????dp.province_name,
        ????count(*)
        FROM?user_behavior_log?ubl
        ????JOIN?dim_province?dp?ON?ubl.province?=?dp.province_name
        GROUP?BY
        ????dp.region_name,
        ????dp.province_name
        ORDER?BY
        ????count(*)?desc?--?Hive不支持

        可以寫(xiě)成下面的形式:

        --?注意:MySQL、Impala支持這種寫(xiě)法,Hive不支持
        SELECT
        ????dp.region_name,?
        ????dp.province_name,
        ????count(*)
        FROM?user_behavior_log?ubl
        ????JOIN?dim_province?dp?ON?ubl.province?=?dp.province_name
        GROUP?BY?1,2
        ORDER?BY?3?

        這樣寫(xiě)有如下的好處:

        • 可以節(jié)省行:通過(guò)許多字段進(jìn)行分組不僅會(huì)在SELECT子句中添加更多行,還會(huì)在GROUP BY和ORDER BY子句中添加更多行,甚至可能使查詢中的行數(shù)增加一倍。
        • 可維護(hù)性:如果想改變分組字段,只需在SELECT子句中進(jìn)行操作,在GROUP BY語(yǔ)句中不需要修改。
        • 方便:只需要GROUP BY 1,2,3,…,n,其中n為分組列的字段序號(hào)。

        使用Common Table表達(dá)式(with語(yǔ)句)

        該方式稱之為Common Table Expressions(CTE),用來(lái)簡(jiǎn)化復(fù)雜查詢。它們可以定義為臨時(shí)視圖,因?yàn)樗鼈儍H在整個(gè)查詢執(zhí)行期間存在。

        看一個(gè)簡(jiǎn)單的例子:

        --?注意Hive、Impala支持這種語(yǔ)法,低版本的MySQL不支持(高版本支持)
        WITH?employee_by_title_count?AS?(
        ????SELECT
        ????????t.name?as?job_title
        ????????,?COUNT(e.id)?as?amount_of_employees
        ????FROM?employees?e
        ????????JOIN?job_titles?t?on?e.job_title_id?=?t.id
        ????GROUP?BY?1
        ),
        salaries_by_title?AS?(
        ?????SELECT
        ?????????name?as?job_title
        ?????????,?salary
        ?????FROM?job_titles
        )
        SELECT?*
        FROM?employee_by_title_count?e
        ????JOIN?salaries_by_title?s?ON?s.job_title?=?e.job_title

        上面的語(yǔ)句中,最終的查詢使用employee_by_titlesalaries_by_title的兩個(gè)結(jié)果集進(jìn)行JOIN產(chǎn)生最終結(jié)果。這比在SELECT子句中或直接在FROM子句中進(jìn)行子查詢更具可讀性和可維護(hù)性。

        使用具有描述性的別名

        這一點(diǎn)非常重要,如果查詢的列字段很多,肯能會(huì)存在一些id,count(*)等,很難辨識(shí)代表什么含義,所以需要為每個(gè)查詢列加上可讀的、易于理解的別名,能夠讓其他人一眼就能看出代表什么含義,這樣可以增加腳本的可維護(hù)性。

        總結(jié)

        文中提到的一些規(guī)范有些是必須要遵守的,有些是個(gè)人的編碼習(xí)慣,無(wú)論你是開(kāi)發(fā)人員、數(shù)據(jù)分析師、數(shù)倉(cāng)開(kāi)發(fā),遵循一些規(guī)范可以避免不必要的麻煩。值得注意的是,關(guān)于SQL的格式,沒(méi)有一個(gè)標(biāo)準(zhǔn)的約定,需要與團(tuán)隊(duì)的其他成員達(dá)成共識(shí),一起按照相同的約定進(jìn)行開(kāi)發(fā),從而可以大大提高腳本的可讀性和可維護(hù)性。

        瀏覽 43
        點(diǎn)贊
        評(píng)論
        收藏
        分享

        手機(jī)掃一掃分享

        分享
        舉報(bào)
        評(píng)論
        圖片
        表情
        推薦
        點(diǎn)贊
        評(píng)論
        收藏
        分享

        手機(jī)掃一掃分享

        分享
        舉報(bào)
          
          

            1. 精品美女在线 | 成人精品一级毛片 | 午夜爽爽爽羞羞视频影院 | 免费无码婬片AAAA片 | 国产一级婬 |