程序員必知必會的SQL用法

本文講解的知識點(diǎn)主要有 ? :公用表表達(dá)式(CTE)油宜、窗口函數(shù)希痴、SQL NULL 函數(shù)及SQL 條件判斷者甲;針對人群:對SQL一知半解,停留在增刪改查初級層面砌创,大神可以飄過虏缸。

一鲫懒、公用表表達(dá)式(Common Table Expression,CTE)

? ? ? ? CTE 可以作為臨時(shí)的結(jié)果集刽辙,可以在DML(Data Manipulation Language)語句中被多次引用窥岩,從而是語句更加簡練。

公用表達(dá)式定義 :

WITH express_name [(colum_name[,....n])]

AS

(CTE_query_definition)

(1)參數(shù)含義?

? ? ? ? express_name:公用表表達(dá)式名字宰缤;

? ? ? ?colum_name :字段名颂翼;

? ? ? ?CTE_query_definition:一個(gè)Select語句。

(2)CTE特點(diǎn)?

? ? ? ?1)在一定程度上提高SQL語句的可讀性

? ? ? ? 2)提高SQL語句執(zhí)行性能

? ? ? ? 在多表進(jìn)行 full join on (MySQL 目前不支持)慨灭,每個(gè)部分都需要使用 一個(gè)select 查詢結(jié)果集時(shí)朦乏,相應(yīng)每個(gè)部分都需要去執(zhí)行一遍,而使用WITH AS 語句 氧骤,則需執(zhí)行一次 呻疹;另外,SQL優(yōu)化器也會對WITH AS 短語做優(yōu)化语淘,連續(xù)被調(diào)用兩次以上诲宇,優(yōu)化器會自動(dòng)將WITH AS 短語的結(jié)果集存放在一個(gè)臨時(shí)表中际歼。

? ? ? ? 3)可以在一個(gè)語句中多次引用公用表表達(dá)式

? ? ? ? 4)可以定義遞歸共用表表達(dá)式

實(shí)例講解?:

獲取某APP每一天不同平臺dau數(shù)據(jù)

這個(gè)好辦惶翻,弄一個(gè)表變量不就可以了嗎

? ? ? ?一運(yùn)行報(bào)錯(cuò),查找一下PostgreSQL中并不支持declare 方式創(chuàng)建表變量鹅心,PostgreSQL只有通過函數(shù)返回record or ref Cursor吕粗。(MySQL支持)

declare 定義表變量
CTE方式

二、窗口函數(shù)

?在將窗口函數(shù)前旭愧,先來對比一下聚合函數(shù)(min() /max() /avg()/ sum()等) 和 窗口函數(shù) :

(1)聚合函數(shù)返回的各個(gè)分組的結(jié)果颅筋,窗口函數(shù)則為每一行返回結(jié)果

? ? ? ?窗口函數(shù)計(jì)算一些行集合的數(shù)據(jù),與常規(guī)的聚集函數(shù)不同的是输枯,窗口函數(shù)不會將參與計(jì)算的行合并成一行輸出议泵,而是保留它們原來的樣子。

(2)聚合函數(shù)都支持窗口函數(shù)運(yùn)算桃熄。

(3)聚合函數(shù)對一組值執(zhí)行計(jì)算先口,并返回單個(gè)值。 除了 COUNT 以外瞳收,聚合函數(shù)都會忽略空值碉京。 聚合函數(shù)經(jīng)常與 SELECT 語句的 GROUP BY 子句一起使用。

(4)窗口函數(shù)是對一組值進(jìn)行操作螟深,不需要使用GROUP BY 子句對數(shù)據(jù)進(jìn)行分組谐宙,能夠在同一行中同時(shí)返回基礎(chǔ)行和聚合列。

實(shí)例講解 :

假設(shè)現(xiàn)在要得到某APP所有版本crash率的平均值界弧,按照通常的做法凡蜻,一定是通過聚合函數(shù)AVG來求Crash率的平均值搭综,輸出結(jié)果中包含該APP 對應(yīng)的版本、crash率及平均crash率划栓。

(1)方法 1 (初學(xué)者經(jīng)常犯的錯(cuò)誤

出錯(cuò)原因 :Select 指定字段要么包含在聚合函數(shù)中设凹,那么包含在Group By語句后面(Group by 對Select指定字段做了限制)。

(2)方法2?

使用方法1 碰壁后 茅姜,立馬改寫成如下方式 闪朱,一看查詢結(jié)果立馬尷尬了,都按 version 和crash_rate Group by 了 钻洒,還求啥avg?

上述 兩種方法均未達(dá)到我們的目的奋姿,上一節(jié)介紹了公用表達(dá)式(CTE),那我們就先用這種方式來實(shí)現(xiàn) :

(3)CTE方式實(shí)現(xiàn)

CTE 方式實(shí)現(xiàn)

那有沒有更加簡單的方式了 ,咱也不賣關(guān)子了 素标,竟然是將窗口函數(shù)称诗,那肯定可用窗口函數(shù)來實(shí)現(xiàn)了

(4)窗口函數(shù)實(shí)現(xiàn)

窗口函數(shù)實(shí)現(xiàn)

窗口函數(shù)的作用是不是很強(qiáng)大 ,使用也相當(dāng)簡單 头遭。

窗口函數(shù)使用OVER函數(shù)實(shí)現(xiàn)寓免,OVER函數(shù)分帶參和不帶參兩種。

OVER 函數(shù)定義:

OVER([PARTITION BY value_expression,..[n] ],<ORDER BY BY_Clause>?)

其中可選參數(shù)PARTITION BY用于將數(shù)據(jù)按照特定字段分組 ; ORDER BY 用于排序计维。


三袜香、SQL NULL 函數(shù)

不同的DB對應(yīng)的SQL NULL 函數(shù)均有所不同,目前SQL NULL函數(shù) 主要有以下幾種:

(1)ISNULL() —— SQL Server/MS Access

(2)NVL() —— Oracle

(3)IFNULL() —— MySQL

(4)COALESCE() —— MySQL / PostgreSQL

用法很簡單鲫惶,以COALESCE()為例蜈首,COALESCE(data,defaultValue) ,如果data為NULL欠母,那么COALESCE(data,defaultValue) 將返回 defaultValue 欢策,反之 ,返回data赏淌。

為什么數(shù)據(jù)庫中很在意對NULL的處理踩寇,這牽扯到SQL的三值邏輯 ,True(真)? 六水、False(假)俺孙、 UNKNOWN(不知道,不確定)缩擂,在數(shù)據(jù)庫中的NULL 相當(dāng)于UNKNOWN鼠冕,若對NULL值處理不當(dāng)會造成意想不到的后果。

實(shí)例:新版app在原有上報(bào)基礎(chǔ)上胯盯,新增了某些上報(bào)字段(沒有設(shè)置默認(rèn)值懈费,深坑), 后期需要對這個(gè)數(shù)據(jù)進(jìn)行統(tǒng)計(jì)分析 博脑,如 ?某版本得分 = sum( 根據(jù)各項(xiàng)指標(biāo)得分 * 權(quán)重)憎乙。

結(jié)果發(fā)現(xiàn) 低版本的得分為NULL 票罐,原因很簡單 ?某些字段只在高版本中才上報(bào),而 NULL+ 數(shù)字 = NULL 泞边。

正確做法:(1)Create Table 時(shí)该押,設(shè)置字段默認(rèn)值 ;

(2)沒有默認(rèn)值阵谚,則可利用上述的SQL NULL 函數(shù)來實(shí)現(xiàn)蚕礼。



三、SQL 條件判斷(簡要列舉)

(1) case when ?及if?

(2) insert into? ....? where not exists () 及insert overwrite

? ? ? ? ?某些數(shù)據(jù)庫不支持replace 梢什,如 PostgreSQL


引用:

(1)http://www.cnblogs.com/CareySon/archive/2011/12/12/2284740.html

(2)http://www.w3school.com.cn/sql/sql_isnull.asp

(3)https://segmentfault.com/a/1190000008332604?utm_source=tuicool&utm_medium=referral

(4)http://www.cnblogs.com/jeffwongishandsome/archive/2010/12/04/1896672.html

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末奠蹬,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子嗡午,更是在濱河造成了極大的恐慌囤躁,老刑警劉巖,帶你破解...
    沈念sama閱讀 212,454評論 6 493
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件荔睹,死亡現(xiàn)場離奇詭異狸演,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)僻他,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,553評論 3 385
  • 文/潘曉璐 我一進(jìn)店門宵距,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人中姜,你說我怎么就攤上這事消玄。” “怎么了丢胚?”我有些...
    開封第一講書人閱讀 157,921評論 0 348
  • 文/不壞的土叔 我叫張陵,是天一觀的道長受扳。 經(jīng)常有香客問我携龟,道長,這世上最難降的妖魔是什么勘高? 我笑而不...
    開封第一講書人閱讀 56,648評論 1 284
  • 正文 為了忘掉前任峡蟋,我火速辦了婚禮,結(jié)果婚禮上华望,老公的妹妹穿的比我還像新娘蕊蝗。我一直安慰自己,他們只是感情好赖舟,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,770評論 6 386
  • 文/花漫 我一把揭開白布蓬戚。 她就那樣靜靜地躺著,像睡著了一般宾抓。 火紅的嫁衣襯著肌膚如雪子漩。 梳的紋絲不亂的頭發(fā)上豫喧,一...
    開封第一講書人閱讀 49,950評論 1 291
  • 那天,我揣著相機(jī)與錄音幢泼,去河邊找鬼紧显。 笑死,一個(gè)胖子當(dāng)著我的面吹牛缕棵,可吹牛的內(nèi)容都是我干的孵班。 我是一名探鬼主播,決...
    沈念sama閱讀 39,090評論 3 410
  • 文/蒼蘭香墨 我猛地睜開眼招驴,長吁一口氣:“原來是場噩夢啊……” “哼重父!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起忽匈,我...
    開封第一講書人閱讀 37,817評論 0 268
  • 序言:老撾萬榮一對情侶失蹤房午,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后丹允,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體郭厌,經(jīng)...
    沈念sama閱讀 44,275評論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,592評論 2 327
  • 正文 我和宋清朗相戀三年雕蔽,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了折柠。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,724評論 1 341
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡批狐,死狀恐怖扇售,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情嚣艇,我是刑警寧澤承冰,帶...
    沈念sama閱讀 34,409評論 4 333
  • 正文 年R本政府宣布,位于F島的核電站食零,受9級特大地震影響困乒,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜贰谣,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 40,052評論 3 316
  • 文/蒙蒙 一娜搂、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧吱抚,春花似錦百宇、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,815評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春因痛,著一層夾襖步出監(jiān)牢的瞬間婚苹,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,043評論 1 266
  • 我被黑心中介騙來泰國打工鸵膏, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留膊升,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 46,503評論 2 361
  • 正文 我出身青樓谭企,卻偏偏與公主長得像廓译,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個(gè)殘疾皇子债查,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,627評論 2 350

推薦閱讀更多精彩內(nèi)容