Mysql學習筆記四:查詢

在關係數據庫中,最常用的操作就是查詢。

基本查詢

要查詢數據庫表的數據,我們使用如下的SQL語句:

SELECT * FROM <表名>

SELECT查詢的結果是一個二維表。

條件查詢

使用SELECT * FROM <表名>可以查詢到一張表的所有記錄。但是很多時候並不希望獲得所有記錄,而是根據條件選擇性地獲取指定條件的記錄。

SELECT語句可以通過WHERE條件來設定查詢條件,查詢結果是滿足查詢條件的記錄。

例如查詢學生表中成績大於90的學生記錄:

SELECT * FROM students WHERE score>=90;

使用AND表示並列條件:

SELECT FROM * students WHERE score>=90 AND gender='F';

使用OR 表示邏輯或:

SELECT FROM * students WHERE score >=90 OR gender ='F';

組合條件使用小括號()包裹:

SELECT FROM * students WHERE (score>=60 AND score<=90) OR gender='F';

使用LIKE 表示相似,其中%符號表示任意字符:

SELECT FROM * WHERE name LIKE '小%';

條件運算優先級次序爲:NOT > AND > OR

投影查詢

使用SELECT * FROM <表名> WHERE <條件>可以選出表中的若干條記錄。我們注意到返回的二維表結構和原表是相同的,即結果集的所有列與原表的所有列都一一對應。

如果我們只希望返回某些列的數據,而不是所有列的數據,我們可以用SELECT 列1, 列2, 列3 FROM ...,讓結果集僅包含指定列。這種操作稱爲投影查詢。

使用SELECT 列1, 列2, 列3 FROM ...時,還可以給每一列起個別名,這樣,結果集的列名就可以與原表的列名不同。它的語法是SELECT 列1 別名1, 列2 別名2 FROM ...

SELECT id pk,name nickname FROM students WHERE score>90;

排序

我們使用SELECT查詢時,查詢結果集通常是按照id排序的,也就是根據主鍵排序。如果我們要根據其他條件排序怎麼辦?可以加上ORDER BY子句。

SELECT id,name,gender score FROM studentd ORDER BY score;

如果要反過來,按照成績從高到底排序,我們可以加上DESC表示“倒序”:

SELECT id,name,gender score FROM studentd ORDER BY score DESC;

如果score列有相同的數據,要進一步排序,可以繼續添加列名。例如,使用ORDER BY score DESC, gender表示先按score列倒序,如果有相同分數的,再按gender列排序:

SELECT id, name, gender, score FROM students ORDER BY score DESC, gender;

默認的排序規則是ASC:“升序”,即從小到大。ASC可以省略。

如果有WHERE子句,那麼ORDER BY子句要放到WHERE子句後面。

SELECT id, name, gender, score FROM students WHERE class_id=1 ORDER BY score DESC;

分頁查詢

使用SELECT查詢時,如果結果集數據量很大,放在一個頁面顯示的話數據量太大,不如分頁顯示。

這個查詢可以通過LIMIT <M> OFFSET <N>子句實現:

SELECT id, name, gender, score FROM students ORDER BY score DESC
LIMIT 3 OFFSET 0;

上述查詢LIMIT 3 OFFSET 0表示,對結果集從0號記錄開始,最多取3條。

如果要查詢第2頁,那麼我們只需要“跳過”頭3條記錄,也就是對結果集從3號記錄開始查詢,把OFFSET設定爲3:

SELECT id, name, gender, score FROM students ORDER BY score DESC
LIMIT 3 OFFSET 3;

MySQL中,LIMIT 15 OFFSET 30還可以簡寫成LIMIT 30, 15

使用LIMIT <M> OFFSET <N>分頁時,隨着N越來越大,查詢效率也會越來越低。

聚合查詢

如果我們要統計一張表的數據量,例如,想查詢students表一共有多少條記錄,難道必須用SELECT * FROM students查出來然後再數一數有多少行嗎?

這個方法當然可以,但是比較弱智。對於統計總數、平均數這類計算,SQL提供了專門的聚合函數,使用聚合函數進行查詢,就是聚合查詢,它可以快速獲得結果。

仍然以查詢students表一共有多少條記錄爲例,我們可以使用SQL內置的COUNT()函數查詢:

SELECT COUNT(*) boys FROM students WHERE gender='M';

除了COUNT()函數外,SQL還提供瞭如下聚合函數:

函數 說明
SUM 計算某一列的合計值,該列必須爲數值類型
AVG 計算某一列的平均值,該列必須爲數值類型
MAX 計算某一列的最大值
MIN 計算某一列的最小值

要特別注意:如果聚合查詢的WHERE條件沒有匹配到任何行,COUNT()會返回0,而SUM()AVG()MAX()MIN()會返回NULL

分組

SQL提供了“分組聚合”的功能來實現對多個組別的聚合:

SELECT class_id,COUNT(*) num FROM students GROUP BY class_id;

也可以使用多個列進行分組。例如,我們想統計各班的男生和女生人數:

SELECT class_id, gender, COUNT(*) num FROM students GROUP BY class_id, gender;

跨表查詢

SELECT查詢不但可以從一張表查詢數據,還可以從多張表同時查詢數據。查詢多張表的語法是:SELECT * FROM <表1> <表2>

SELECT * FROM students, classes;

這種一次查詢兩個表的數據,查詢的結果也是一個二維表,它是students表和classes表的“乘積”,即students表的每一行與classes表的每一行都兩兩拼在一起返回。結果集的列數是students表和classes表的列數之和,行數是students表和classes表的行數之積。

這種多表查詢又稱笛卡爾查詢,使用笛卡爾查詢時要非常小心,由於結果集是目標表的行數乘積,對兩個各自有100行記錄的表進行笛卡爾查詢將返回1萬條記錄,對兩個各自有1萬行記錄的表進行笛卡爾查詢將返回1億條記錄。

上述查詢的結果集有兩列id和兩列name,兩列id是因爲其中一列是students表的id,而另一列是classes表的id,但是在結果集中,不好區分。要解決這個問題,我們仍然可以利用投影查詢的“設置列的別名”來給兩個表各自的idname列起別名:

SELECT
    students.id sid,
    students.name,
    students.gender,
    students.score,
    classes.id cid,
    classes.name cname
FROM students, classes;

表名.列名這種方式列舉兩個表的所有列實在是很麻煩,所以SQL還允許給表設置一個別名,讓我們在投影查詢中引用起來稍微簡潔一點:

SELECT
    s.id sid,
    s.name,
    s.gender,
    s.score,
    c.id cid,
    c.name cname
FROM students s, classes c;

連接查詢

連接查詢是另一種類型的多表查詢。連接查詢對多個表進行JOIN運算,簡單地說,就是先確定一個主表作爲結果集,然後,把其他表的行有選擇性地“連接”在主表結果集上。

最常用的一種是內連接INNER JOIN,其原理示意圖如下:

SELECT s.id, s.name, s.class_id, c.name class_name, s.gender, s.score
FROM students s
INNER JOIN classes c
ON s.class_id = c.id;

其次有外連接,包括:左連接、右連接和全連接

LEFT/RIGHT/FULL OUTER JOIN
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章