一.理解group by和聚合函數
先來看下表1,表名為test:
表1
執行如下SQL語句:
1
2
|
SELECT
name
FROM
test
GROUP
BY
name
|
你應該很容易知道運行的結果,沒錯,就是下表2:
表2
可是為了能夠更好的理解“group by”多個列“和”聚合函數“的應用,我建議在思考的過程中,由表1到表2的過程中,增加一個虛構的中間表:虛擬表3。下面說說如何來思考上面SQL語句執行情況:
1.FROM test:該句執行后,應該結果和表1一樣,就是原來的表。
2.FROM test Group BY name:該句執行后,我們想象生成了虛擬表3,如下所圖所示,生成過程是這樣的:group by name,那么找name那一列,具有相同name值的行,合並成一行,如對於name值為aa的,那么<1 aa 2>與<2 aa 3>兩行合並成1行,所有的id值和number值寫到一個單元格里面。
3.接下來就要針對虛擬表3執行Select語句了:
(1)如果執行select *的話,那么返回的結果應該是虛擬表3,可是id和number中有的單元格里面的內容是多個值的,而關系數據庫就是基於關系的,單元格中是不允許有多個值的,所以你看,執行select * 語句就報錯了。
(2)我們再看name列,每個單元格只有一個數據,所以我們select name的話,就沒有問題了。為什么name列每個單元格只有一個值呢,因為我們就是用name列來group by的。
(3)那么對於id和number里面的單元格有多個數據的情況怎么辦呢?答案就是用聚合函數,聚合函數就用來輸入多個數據,輸出一個數據的。如cout(id),sum(number),而每個聚合函數的輸入就是每一個多數據的單元格。
(4)例如我們執行select name,sum(number) from test group by name,那么sum就對虛擬表3的number列的每個單元格進行sum操作,例如對name為aa的那一行的number列執行sum操作,即2+3,返回5,最后執行結果如下:
(5)group by 多個字段該怎么理解呢:如group by name,number,我們可以把name和number 看成一個整體字段,以他們整體來進行分組的。如下圖
(6)接下來就可以配合select和聚合函數進行操作了。如執行select name,sum(id) from test group by name,number,結果如下圖:
實際的例子,如下兩表
下面這個sql語句
--.統計每個系的學生人數。
SELECT Sdept 系別,COUNT(*) 人數
FROM student
WHERE Sdept IN(SELECT DISTINCT Sdept FROM student)
GROUP BY Sdept
--.統計每門課程的修課人數和考試最高分。
SELECT Cname 課程名,COUNT(*) 修課人數,MAX(Grade) 考試最高分
FROM SC,course
WHERE SC.Cno IN(SELECT DISTINCT Cno FROM SC ) AND course.Cno=SC.Cno
GROUP BY course.Cname //group by一定要加的,且其后可跟多個列
二. inner join 與 where子句有什么區別?
1 WHERE子句中使用的連接語句,在數據庫語言中,被稱為隱性連接。INNER JOIN……ON子句產生的連接稱為顯性連接。(其他JOIN參數也是顯性連接)WHERE和INNER JOIN產生的連接關系,沒有本質區別,結果也一樣。但是!隱性連接隨着數據庫語言的規范和發展,已經逐漸被淘汰,比較新的數據庫語言基本上已經拋棄了隱性連接,全部采用顯性連接了。
2無論怎么連接,都可以用join子句,但是連接同一個表的時候,注意要定義別名,否則產生錯誤!
a> inner join:理解為“有效連接”,兩張表中都有的數據才會顯示left join:理解為“有左顯示”,比如on a.field=b.field,則顯示a表中存在的全部數據及a\\b中都有的數據,A中有、B沒有的數據以null顯示
b> right join:理解為“有右顯示”,比如on a.field=b.field,則顯示B表中存在的全部數據及a\\b中都有的數據,B中有、A沒有的數據以null顯示
c> full join:理解為“全連接”,兩張表中所有數據都顯示,實際就是inner+(left-inner)+(right-inner)
3 join可以分主次表 外聯接有三種類型:完全外聯,左聯,右聯.
完全外聯包含兩張表的所有記錄.
左聯是以左邊的表為主,右邊的為輔,右聯則相反
4一般要使得數據庫查詢語句性能好點遵循一下原則:
在做表與表的連接查詢時,大表在前,小表在后
不使用表別名,通過字段前綴區分不同表中的字段
查詢條件中的限制條件要寫在表連接條件前
盡量使用索引的字段做為查詢條件
另附一個sql學習推薦https://www.zhihu.com/question/19552975