詳解MySQL分組連結的使用技巧
MYSQL中的分組和連結是在操作資料庫和資料互動時最常用的兩個在功能,把這兩項處理好了,MYSQL的執行效率會非常高速。
一、group by ,分組
顧名思義,把資料按什麼來分組,每一組都有什麼特點。
1、我們先從最簡單的開始:
select count(*) from tb1 group by tb1.sex;
查詢所有資料的條數,按性別來分組。這樣查詢到的結果集只有一列count(*)。
2、然後我們來分析一下,這個分組,我們能在select 和 from 之間放一些什麼呢?
當資料分組之後,資料的大部分欄位都將失去它存在的意義,大家想想,多條資料的同一列,只顯示一個值,那到底顯示誰的,這個值有用嗎?
通過思考,不難發現,只有by的那些列可以放進去,然後就是sql的函式操作了,比如count(),sum()……(包含在by後面作為分組的依據,包含在聚合函式中作為結果)
例:查詢每個學院的學生有多少人:(學院的值是學院的id)
SELECT a.COLLEGE AS 學院,COUNT(*) AS 學生人數 FROM base_alumni a GROUP BY a.COLLEGE;
3、where,having,和group by聯合使用
在最初學習group by的時候,我就陷入了一個誤區,那就是group by不能和where一起使用,只能用having……
看書不認真啊,其實它們都是可以一起使用的,只不過是where只能在group by 的前面,having只能在group by 的後面。
where,過濾條件的關鍵字,但是它只能對group by之前的資料進行過濾篩選;
having,也是過濾條件的關鍵字作用和where是一樣的,但是它過濾的是分組後的資料,就是對分組後得到的結果集進行過濾篩選。
出現having其實我覺得就是為了解決一條語句出現兩個where的問題,把它們區分開來
例:
查詢 30100學院的每個專業的學生有多少人。
SELECT a.MAJOR AS 專業,COUNT(*) AS 學生人數 FROM base_alumni a WHERE a.COLLEGE = 30100 GROUP BY a.MAJOR;
查詢每個學院的學生有多少人,並且只要學生人數大於3的。
SELECT a.COLLEGE AS 學院,COUNT(*) AS 學生人數 FROM base_alumni a GROUP BY a.COLLEGE HAVING COUNT(*)>3;
濾清執行順序:①先對*進行篩選,②對篩選的結果進行分組,③對分組的結果進行篩選
4、Group By All 的使用,哈哈哈哈,經常網上的查閱,我決定淘汰這個語法~
其實就是前面where之後,想要分組的結果顯示不符合where的資料,當然,不做運算,運算結果用0或null表示,感覺這語法沒啥用,想不出應用場景~
二、深入學習 連線
連線分4種,內連線,全連線,左外連線,右外連線
1、連接出現的地方
①from和where之間,做表和表的連線
②where和having之間,having是對group by的結果集進行篩選,就是把group by的結果集作為一張表,然後可以再和別的表做連線,再進一步篩選
2、連線型別解讀
把表看成是一個集合,連線看成是對映,那麼它們的結果
內連線:一一對映;全連線:笛卡爾乘積;左外連線:一一對映+左表對應右表的null;右外連線:一一對映+右表對應左表的null。
關鍵字:
內連線:inner join;全連線:cross join;左外連線:left join;右外連線:right join 。
語法:
表a left join 表b on a.列1 = b.列2
3、連線的使用
之前學習group by的例子中,結果集是存在bug的。
例:查詢每個學院的學生有多少人:(學院的值是學院的id),在沒有連線的時候,學院人數為0的是顯示不出來的,因為當前表中就沒有這個學院的資訊
那麼我們在這裡做一下左連線(左外連線):
SELECT c.ID,a.COLLEGE,COUNT(a.COLLEGE) FROM (SELECT ID FROM dic_college) c LEFT JOIN ( SELECT COLLEGE FROM base_alumni ) a ON c.ID = a.COLLEGE GROUP BY c.ID
我這裡是一個完整的語句了。我在寫出這條語句之前遇到了許多的磕磕碰碰。
解讀它:
我們先把學院表和校友資訊表(學生表)做左連線
因為我們要的是學院,所以學院作為主表,放left join的前面 c LEFT JOIN a ON ...
然後我們發現有很多欄位,於是我們去掉多餘的欄位,這樣既方便我們觀察,也提高了sql的執行效率
①把學院表變成只有一個欄位(SELECT ID FROM dic_college) c
②把學生表變成只有一個欄位( SELECT COLLEGE FROM base_alumni ) a
這時,查詢結果是這樣的
SELECT * FROM (SELECT ID FROM dic_college) c LEFT JOIN ( SELECT COLLEGE FROM base_alumni ) a ON c.ID = a.COLLEGE
這時候,對這個結果集進行分組:GROUP BY c.ID,並且查詢欄位要做更改
在上邊那個結果集中,c.ID和a.COLLEGE是一一對應的,此時,count(*)的資料是總行數,因為我們的主表是學院表,所以這個資料和count(c.ID)的資料是一樣的。
但是a.COLLEGE為空的行的資料中值都是1,這不是我們想要的,所以我們把count(*)改成count(a.COLLEGE),這樣資料就出來了。
這才是查詢所有學院中每個學院的學生人數的正確答案!當然,上邊的截圖只是資料的前幾行,後面還有資料的
4、經過我測試了一下
左連線和右連線……
SELECT * FROM a LEFT JOIN b ON b.ID = a.FK_ID;
SELECT * FROM b RIGHT JOIN a ON b.ID = a.FK_ID;
這兩個語句的結果相同,它兩並沒有發現別的區別。
全連線就是交叉連線,和不使用連線……
SELECT * FROM c,a WHERE c.ID = a.FK_ID;
SELECT * FROM c CROSS JOIN a ON c.ID = a.FK_ID;
這兩個語句也沒有區別。
以上就是本篇關於MYSQL分組和連結深入詳解的全部內容,如果大家還有任何不明白的地方可以在下方留言區討論。