導(dǎo)讀:SQL是所有數(shù)據(jù)從業(yè)者必須打牢的基本功之一,,扎實(shí)的SQL查詢和適當(dāng)?shù)恼{(diào)優(yōu)技巧是檢驗(yàn)SQL能力的兩大重要準(zhǔn)則,。個(gè)人曾經(jīng)專門花費(fèi)過(guò)好多時(shí)間用于提升SQL能力,,期間也刷了大量的SQL題目,在這期間也不斷摸索總結(jié)了一些小技巧,,今天本文就來(lái)分享其中的兩個(gè),,也差不多是日常使用中最為高頻的兩個(gè)了。
為了配合演示這兩個(gè)小技巧,,本文所使用示例數(shù)據(jù)如下,,其實(shí)這也是前幾天推文中所使用的數(shù)據(jù):
SQL的數(shù)據(jù)類型隱式轉(zhuǎn)換
很多編程語(yǔ)言都限定了數(shù)據(jù)類型,例如在Python中字符串“0”和數(shù)值0是不相等的,,布爾型True和數(shù)值1也是不相等,,但在SQL中則不然,其內(nèi)置了數(shù)據(jù)類型隱式轉(zhuǎn)換功能,,所以執(zhí)行查詢 select “0”=0 會(huì)返回1的,,這既說(shuō)明字符串“0”和數(shù)值0是相等的,也說(shuō)明SQL中的布爾值會(huì)自動(dòng)轉(zhuǎn)換為1或0,。
利用這一小技巧,,在實(shí)現(xiàn)很多統(tǒng)計(jì)指標(biāo)時(shí)就可以有很多小技巧。例如計(jì)算學(xué)生成績(jī)表中每名學(xué)生的成績(jī)的優(yōu)秀率,,即成績(jī)?cè)?0分以上的科目與本人總科目的占比,。為實(shí)現(xiàn)這一查詢,常規(guī)的操作是分別統(tǒng)計(jì)每名學(xué)生成績(jī)?cè)?0分以上的科目數(shù)量和總科目,,然后進(jìn)行相除得到占比,。
實(shí)際上,,在給出前述小例子的基礎(chǔ)上,,這一需求可以如下實(shí)現(xiàn):
其中,在每名學(xué)生的分組中,,條件判斷score>=90返回一組0或1的結(jié)果,,對(duì)這組0/1取值進(jìn)行求均值操作,即等價(jià)于求成績(jī)>=90的科目占比。
巧妙運(yùn)用if函數(shù)和null
SQL內(nèi)置了眾多函數(shù),,但對(duì)于一名程序員而言if函數(shù)應(yīng)該尤為常見(jiàn)和常用,;另一方面,null值也是SQL中一個(gè)神奇的存在,,它有兩大特性:一是任何值與null的任何計(jì)算都會(huì)得到null值,;二是在任何聚合函數(shù)中,null值都不參與計(jì)算(例如,,count計(jì)數(shù)就是查找null以外的結(jié)果數(shù)量),。配合使用if函數(shù)和null值,有時(shí)也可實(shí)現(xiàn)很好的效果,。
例如,,仍然針對(duì)以上學(xué)生成績(jī)表,需要分別統(tǒng)計(jì)每名學(xué)生成績(jī)?cè)?0分以上成績(jī)的平均值,,也就是如果成績(jī)>=80則參與最后均值計(jì)算,,否則不參與。配合if函數(shù)和null的特性,,可以如下優(yōu)雅的實(shí)現(xiàn):
實(shí)際上,,上述查詢語(yǔ)句中,首先通過(guò)if函數(shù)衍生一個(gè)臨時(shí)字段if(score>=80, score, null)其取值為:成績(jī)≥80時(shí)取成績(jī)值,,否則置為null,,即相當(dāng)于僅保留了成績(jī)?cè)?0分以上的記錄;而后嵌套一層avg函數(shù)即直接實(shí)現(xiàn)了計(jì)算80分以上平均值的效果,。
當(dāng)然,,對(duì)于這一需求也可以先用where條件過(guò)濾出成績(jī)?cè)?0分以上的記錄后再聚合統(tǒng)計(jì)。