一区二区三区日韩精品-日韩经典一区二区三区-五月激情综合丁香婷婷-欧美精品中文字幕专区

分享

SQL,從熟練到掌握

 zhaohuijiang 2017-02-28

每日干貨好文分享丨請點(diǎn)擊+關(guān)注

歡迎關(guān)注天善智能微信公眾號,我們是專注于商業(yè)智能BI,大數(shù)據(jù),數(shù)據(jù)分析領(lǐng)域的垂直社區(qū)。

對商業(yè)智能BI、數(shù)據(jù)分析挖掘、大數(shù)據(jù)、機(jī)器學(xué)習(xí),python,R感興趣同學(xué)加微信:fridaybifly,邀請你進(jìn)入頭條數(shù)據(jù)愛好者交流群,數(shù)據(jù)愛好者們都在這兒。

我們在上一篇《SQL,從入門到熟練》文章已經(jīng)掌握了除Join外的常用語法和函數(shù),今天會通過一系列的練習(xí)徹底掌握SQL。

我們知道,數(shù)據(jù)庫由多張表組成,表與表之間可以實(shí)現(xiàn)關(guān)聯(lián)。

SQL,從熟練到掌握

上圖就是一個簡單的關(guān)聯(lián)模型:

Students.addressId = Address.idStudents.id = Scores.studentIdScores.courseId = Courses.id

那么,如何在SQL查詢語句中將兩個表聯(lián)接起來?我們將運(yùn)用最重要的語法Join。

select * from Studentsjoin Address on Students.addressId = Address.id

上面語句,join將Students和Address兩表關(guān)聯(lián),關(guān)聯(lián)需要一個或多個字段作為聯(lián)接橋梁。例子中的橋梁就是addressid,我們使用on語句,將Students表的addressId字段和Address的id字段匹配。

這里需要注意的是,因為字段可能重名,所以一旦使用了Join,字段前應(yīng)該加上表名,如Students.addressId和Address.id ,這種用法是為了字段的唯一性,否則遇到重名,系統(tǒng)不知道使用哪個字段,就會報錯。

select * from Students as sjoin Address as a on s.addressId = a.id

上圖是更優(yōu)雅的寫法,將表命名為一個縮略的別名,避免了語句過于冗余。不要使用拼音做別名,不是好習(xí)慣。

Join語法有很多不同的變形,Left Join,Outer Join等,新人很容易混淆。這個我們可以用數(shù)學(xué)中的交集和并集掌握。

SQL,從熟練到掌握

上圖很清晰地解釋了各Join語法。

Inner Join最常見,叫做內(nèi)聯(lián)接,可以縮寫成Join,找的是兩張表共同擁有的字段。

Left Join叫做左聯(lián)接,以左表(join符號前的那張表)為主,返回所有的行。如果右表有共同字段,則一并返回,如果沒有,則為空。

我們以W3School上的數(shù)據(jù)為例:

SQL,從熟練到掌握

select Persons.LastName, Persons.FirstName, Orders.OrderNofrom Personsleft join Orders on Persons.Id_P=Orders.Id_Porder by Persons.LastName

于是輸出結(jié)果為:

SQL,從熟練到掌握

結(jié)果集中,Bush那一行的OrderNo為空,就是因為Id_P無法匹配上,返回了Null。如果改成Inner join,則不會返回整個Bush所在行。這是Inner Join和Left Join的區(qū)別,也是面試中經(jīng)常會問到的題目。

Right Join和Left Join沒有區(qū)別,A Left Join B 等價于 B Right Join A。

Full Join叫做全聯(lián)接,也叫做Full Outer Join,意思是不管有的沒的,只要存在,就返回。

還是以之前的例子演示,下面是Full Join:

SQL,從熟練到掌握

最后兩行就是所謂的「不管有的沒的,只要存在字符串,就返回」的結(jié)果,它們Id_P并沒有匹配上,但還是給出了返回,只是為空字段不同。

這三者的關(guān)系,我們可以理解為:A Full Join B = A Left Join B + A Right Join B - A Inner Join B,這就是數(shù)學(xué)上的集合運(yùn)算,雖然SQL的表并不能加減法。如果還一知半解,看最上面的Join示例圖,用面積的角度看也明白了。

通過上面的例子,我們已經(jīng)掌握了Join的主流語法,其他無非是變種。比如加約束條件 where XX is null,這里的XX可以是結(jié)果為空的字段。拿上文Left Join的例子演示:

select Persons.LastName, Persons.FirstName, Orders.OrderNofrom Personsleft join Orderson Persons.Id_P=Orders.Id_Pwhere Orders.Id_P is Null

最終返回的結(jié)果就是Bush這一行。

當(dāng)我們有多個字段要匹配時,on后面可以通過 and 進(jìn)行多項關(guān)聯(lián)。

select * from Ajoin B on A.name = B.name and A.phone = B.phone

上圖就是一個簡單的適用場景,將用戶姓名和手機(jī)號進(jìn)行多項關(guān)聯(lián)。它也可以加入其他的條件判斷。

select * from Ajoin B on A.name = B.name and A.phone = B.phone and B.sex = '男

我們再加一個and,將B表的用戶性別限定為男。這種用法等價于where B.sex = '男'。當(dāng)數(shù)據(jù)量大到一定程度,通過這種約束條件,能優(yōu)化查詢性能。

到這里,SQL的常用語法已經(jīng)講解的差不多了,我們進(jìn)行實(shí)戰(zhàn)吧。leetcode.com網(wǎng)站是知名的算法競賽題,去上面刷SQL吧。

注冊完后進(jìn)入leetcode.com/problemset/database頁面。那里有幾道MySQL題目。因為時間關(guān)系,我只講解Join相關(guān),大家有興趣可以刷其他題,都不難的。SQLZoo也能刷,就是頁面丑了點(diǎn),所以我十分感動地拒絕了它。

SQL,從熟練到掌握

我們從Easy開始,選擇題目Combine Two Tables。

SQL,從熟練到掌握

紅色字符是表名,第一列是字段名,第二列是數(shù)據(jù)類型。題目希望我們通過兩張表輸出:FirstName, LastName, City, State四個字段。

單純的Inner Join就能完成了。記住噢,答案需要完全一致,也就是說最終的結(jié)果必須是四個字段,不能多不能少,順序也不能亂,大小寫要嚴(yán)格。這一題大家自己做吧。通過后會有個綠色的Accepted提示。

接下來選擇Medium難度的Department Highest Salary。

SQL,從熟練到掌握

這里有兩張表,員工表和部門表,我們希望找出各個部門的最高薪水。

部門信息單獨(dú)為一張表,首先我們需要Join關(guān)聯(lián)起來,將部門分組求出最大值:

select d.Id, #這是部門ID d.Name as Name, #這是部門名字 max(e.Salary) as Salary #這是最高薪水from Department djoin Employee eon e.DepartmentId = d.Idgroup by d.Id

上述的查詢語句找出了最高薪水的部門,我們是否能直接使用其作為答案?不能。這里有一個邏輯的小陷阱,當(dāng)最高薪水非單個時,使用max會只保留第一個,而不是列舉所有,所以我們需要更復(fù)雜的查詢。

因為已經(jīng)有了各部門最高薪水的數(shù)據(jù),可以將它作為一張新表,用最高薪水關(guān)聯(lián)雇員表,獲得我們最終的答案。

SQL,從熟練到掌握

上面就是最終解法(#是解釋給你們看的,中文會報錯的),當(dāng)然解法應(yīng)該不是唯一的,大家有興趣可以繼續(xù)研究。

最終,我們選Hard模式的Department Top Three Salaries。

范例數(shù)據(jù)沒有一丁點(diǎn)變化,它需要我們求出各部門薪水前三的數(shù)據(jù)。如果最高薪水只有兩個,則輸出兩個。

SQL,從熟練到掌握

上圖是給的范例結(jié)果。

排名前三的數(shù)據(jù),我們可以使用order by 降序排列出來,然后通過limit 限定為3,但是新的問題是:既要各部門前三,也存在排名并列的情況。此時order by就無能為力了。

如果是SQL Server或者Oracle,我們可以使用row_number分組排序函數(shù),但是MySQL沒有,其中的一種思路是利用set語法設(shè)置變量,間接應(yīng)用row_number。我們還能使用另外一種思路。

select * from Employee as ewhere ( select count(distinct e1.Salary) from Employee e1 where e1.Salary > e.Salary and e1.DepartmentId = e.DepartmentId ) <>

上述的例子巧妙地借用了子查詢。在where語句中,我們用子表e1與父表(外表)e進(jìn)行比對。SQL是允許子查詢的表和父查詢的表進(jìn)行運(yùn)算的。

e1.DepartmentId = e.DepartmentId作為條件約束,避免跨部門。e1.Salary > e.Salary則是邏輯判斷,通過count函數(shù),逐行計算出e表中有多少薪水比e1的薪水低。

SQL,從熟練到掌握

因為e1表和e表實(shí)際上是等價的。所以返回的count(distinct e1.Salary) 代表e1表有中多少薪水比e表的高,上圖的例子,答案是2(90000和85000比它高)。如果是0,則代表e表中該行薪水最高(沒有比它高的),1代表第二高,2代表第三高。于是便過濾出Top 3的薪水。最后通過join計算出結(jié)果。

SQL,從熟練到掌握

在實(shí)際查詢過程中,不建議大家使用這種運(yùn)算方式,因為運(yùn)算效率不會快。其實(shí)換我,我更可能group by后導(dǎo)出結(jié)果用Excel處理。

到這里,大家對Join已經(jīng)有一個大概的了解了吧。真實(shí)的數(shù)據(jù)查詢場景中,Join會用到很多,業(yè)務(wù)復(fù)雜用五六個Join也是常態(tài),如果算上各類邏輯處理,SQL代碼行數(shù)可以破百。這時候,考驗的就是熟練度了。

SQL只要多加訓(xùn)練,并不是一門很難掌握的語言。除了技巧,還要看你對業(yè)務(wù)表的熟悉程度,一般公司發(fā)展大了,百來張表很正常,各類業(yè)務(wù)邏輯各種Join,各字段的含義,這是同樣要花費(fèi)時間的苦功夫。

希望大家對SQL已經(jīng)有一個初步的掌握了。SQL學(xué)好了,以后應(yīng)用大數(shù)據(jù)的Hive和SparkSQL也是輕而易舉的。

接下來,我們將要進(jìn)入第五周的大魔王課程,統(tǒng)計學(xué),從入門到放棄,哈哈哈。

對商業(yè)智能BI、數(shù)據(jù)分析挖掘、大數(shù)據(jù)、機(jī)器學(xué)習(xí),python,R感興趣同學(xué)加微信:fridaybifly,邀請你進(jìn)入頭條數(shù)據(jù)愛好者交流群,數(shù)據(jù)愛好者們都在這兒。

SQL,從熟練到掌握

轉(zhuǎn)載請保留以下內(nèi)容:

本文來源自天善社區(qū)秦路的博客(公眾號)。

原文地址:https://ask./blog/qinlu/6347 。

    本站是提供個人知識管理的網(wǎng)絡(luò)存儲空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點(diǎn)擊一鍵舉報。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多

    精品人妻一区二区四区| 色丁香一区二区黑人巨大| 国产综合欧美日韩在线精品| 日韩和欧美的一区二区三区 | 中文字幕日韩无套内射| 亚洲国产另类久久精品| 日本亚洲精品在线观看| 精品欧美日韩一区二区三区 | 少妇淫真视频一区二区| 欧洲精品一区二区三区四区| 老司机精品视频在线免费看| 国产精品一区二区成人在线| 欧美激情视频一区二区三区| 国产精品国产亚洲区久久| 亚洲欧美精品伊人久久| 欧美91精品国产自产| 在线观看国产午夜福利| 欧美国产日韩变态另类在线看 | 欧美人妻少妇精品久久性色| 亚洲中文字幕熟女丝袜久久| 大香蕉精品视频一区二区| 亚洲婷婷开心色四房播播| 国产日韩精品激情在线观看| 亚洲国产欧美精品久久| 欧美日本精品视频在线观看| 亚洲精品国产福利在线| 精品香蕉一区二区在线| 美女黄色三级深夜福利| 国产成人亚洲欧美二区综| 中文字幕日韩一区二区不卡 | 亚洲精品国男人在线视频| 人妻人妻人人妻人人澡| 五月综合激情婷婷丁香| 亚洲精品高清国产一线久久| 日韩1区二区三区麻豆| 青青操日老女人的穴穴| 一级欧美一级欧美在线播| 国产亚洲二区精品美女久久 | 亚洲一区二区三区国产| 欧美日韩综合在线第一页| 国产精品超碰在线观看|