1.distinct
distinct用於返回某個字段去重後的記錄
+------+--------+-------+
| id | name | point |
+------+--------+-------+
| 1 | 小明 | 100 |
| 1 | 小紅 | 90 |
| 2 | 小剛 | 80 |
| 3 | 小軍 | 80 |
+------+--------+-------+
使用distincy對id去重
mysql> select distinct id from test;
+------+
| id |
+------+
| 1 |
| 2 |
| 3 |
+------+
如果同時對id和point去重,distinct默認同時滿足id和point重複纔去重,所以如果對上表執行,則結果沒有實際去重效果
(如果想要獲取去重後的完整記錄信息可以使用group by函數)
mysql> select distinct id,point from test;
+------+-------+
| id | point |
+------+-------+
| 1 | 100 |
| 1 | 90 |
| 2 | 80 |
| 3 | 80 |
+------+-------+
distinct更多用於統計某個字段不重複記錄的數量 -- count(distinct name)
mysql> select count(distinct name) from test;
+----------------------+
| count(distinct name) |
+----------------------+
| 4 |
+----------------------+
使用count函數統計某個字段不重複的記錄數,關於count用法後面有介紹
2.group by
group by用於對數據進行分類歸總,將查詢結果按照1個或多個字段進行分組
mysql> select * from test group by id;
+------+--------+-------+
| id | name | point |
+------+--------+-------+
| 1 | 小明 | 100 |
| 2 | 小剛 | 80 |
| 3 | 小軍 | 80 |
+------+--------+-------+
利用group by可以便捷的將數據記錄去重,在by之後添加限定條件,指定需要分組的字段(可以指定多個字段)
3.order by
order by用於對數據進行排序,搭配關鍵字 asc/desc 指定 升降序 ,如不指定則默認從小到大升序(asc)
mysql> select * from test order by id desc;
+------+--------+-------+
| id | name | point |
+------+--------+-------+
| 3 | 小軍 | 80 |
| 2 | 小剛 | 80 |
| 2 | b | 100 |
| 2 | c | 100 |
| 1 | 小明 | 100 |
| 1 | 小紅 | 90 |
| 1 | a | 100 |
+------+--------+-------+
4.sum/min/max
這幾個就跟字面意思一樣,求和/最大值/最小值,用法也比較簡單(還是上面的表格)
mysql> select * from test;
+------+--------+-------+
| id | name | point |
+------+--------+-------+
| 1 | 小明 | 100 |
| 1 | 小紅 | 90 |
| 2 | 小剛 | 80 |
| 3 | 小軍 | 80 |
| 1 | a | 100 |
| 2 | b | 100 |
| 2 | c | 100 |
+------+--------+-------+
mysql> select sum(point) from test;
+------------+
| sum(point) |
+------------+
| 650 |
+------------+
mysql> select max(point) from test;
+------------+
| max(point) |
+------------+
| 100 |
+------------+
mysql> select min(point) from test;
+------------+
| min(point) |
+------------+
| 80 |
+------------+
5.join on
join on主要用於兩表之間的聯合操作
現有表格a,b,形式如下
mysql> select * from a;
+----+------+
| id | name |
+----+------+
| 1 | abc |
| 2 | bcd |
| 3 | cde |
| 4 | def |
+----+------+
mysql> select * from b;
+----+------+
| id | name |
+----+------+
| 3 | cde |
| 4 | def |
| 5 | efg |
| 6 | fgh |
+----+------+
現在要查找a、b兩表間 id 相同的記錄
mysql> select * from a join b on a.id = b.id;
+----+------+----+------+-------+
| id | name | id | name | point |
+----+------+----+------+-------+
| 1 | abc | 1 | abc | 100 |
| 4 | def | 4 | def | 90 |
+----+------+----+------+-------+
可以看出使用 join 後得到兩表id相同的字段的記錄,不過被合併到了一起
如果想只顯示具體重複的字段,可以在 select 後指定(字段需要指定哪個表格,因爲join過後得到的表格包含兩個 id 字段,會產生歧義)
mysql> select a.id, a.name from a join b on a.id = b.id;
+----+------+
| id | name |
+----+------+
| 3 | cde |
| 4 | def |
+----+------+
接下來是關於join的擴展
MySQL默認的join是內連接(inner),就如上面看到的結果,如果加上 left / right 關鍵字變成外連接
mysql> select * from a left join b on a.id = b.id;
+----+------+------+------+-------+
| id | name | id | name | point |
+----+------+------+------+-------+
| 1 | abc | 1 | abc | 100 |
| 2 | bcd | NULL | NULL | NULL |
| 3 | cde | NULL | NULL | NULL |
| 4 | def | 4 | def | 90 |
+----+------+------+------+-------+
可以看到結果爲以表a爲基礎,與表b作對比,沒有相同記錄則爲null,相同記錄就正常顯示
right和left相反,會以b爲基礎與a對比
mysql> select * from a right join b on a.id = b.id;
+------+------+----+------+-------+
| id | name | id | name | point |
+------+------+----+------+-------+
| 1 | abc | 1 | abc | 100 |
| 4 | def | 4 | def | 90 |
| NULL | NULL | 5 | de | 90 |
| NULL | NULL | 6 | dge | 70 |
+------+------+----+------+-------+
注:內連接使用爲默認用法,可以省略inner關鍵字,同樣的,外連接以 left/right 作爲標識,也可以省略 outer 關鍵字(標準寫法--內連接:inner join,外連接: left/right outer join)
6.limit
關鍵字 limit 用於強制SELECT語句返回指定的記錄數。LIMIT 接受一個或兩個數字參數(必須是整數常量)。如果給定兩個參數,第一個參數指定第一個返回記錄行的偏移量,第二個參數指定返回記錄行的最大數目。如果給定一個參數,則作爲返回條數,偏移量默認爲0。
mysql> select * from a;
+----+------+
| id | name |
+----+------+
| 1 | abc |
| 2 | bcd |
| 3 | cde |
| 4 | def |
+----+------+
mysql> select * from a limit 1, 2; # 偏移1條數據,數目爲2,返回2,3兩條數據
+----+------+
| id | name |
+----+------+
| 2 | bcd |
| 3 | cde |
+----+------+
mysql> select * from a limit 2; # 默認偏移量爲 0 ,數目爲2,返回前兩條數據,
+----+------+
| id | name |
+----+------+
| 1 | abc |
| 2 | bcd |
+----+------+
除了給 limit 指定兩個參數外,還可以將偏移量和數目分開指定,偏移量用 offset 接收,效果等同於指定兩個參數的 limit
mysql> select * from a limit 3 offset 1; # 數據條數3,偏移量1,返回2-4三條數據
+----+------+
| id | name |
+----+------+
| 2 | bcd |
| 3 | cde |
| 4 | def |
+----+------+
7.count
count函數的作用是對指定內容進行計數,用法如下
mysql> select * from newtable;
+------+------+-------+
| id | name | point |
+------+------+-------+
| 1 | a | 100 |
| 2 | b | 100 |
| 3 | c | 90 |
| 4 | d | NULL |
| 5 | NULL | NULL |
+------+------+-------+
mysql> select count(*) from newtable; # 統計表格的所有記錄數,包括含有null值的字段的記錄
+----------+
| count(*) |
+----------+
| 5 |
+----------+
mysql> select count(name) from newtable; # 統計‘name’字段,過濾掉null值,只統計有效值記錄
+-------------+
| count(name) |
+-------------+
| 4 |
+-------------+
mysql> select count(point) from newtable; # 同上
+--------------+
| count(point) |
+--------------+
| 3 |
+--------------+
需要注意 count(*) 和 count(column_name) 的兩種用法的區別,count(*) 針對所有字段,可以理解爲當有一個字段不爲空時就算此記錄有效,進行計數;只有當所有字段都爲空纔算記錄無效,而所有字段爲空其實就等於沒有此記錄,自然不參與計數。
8.AS
as一般用於重命名錶名或者列名,爲了簡化語句或者改變輸出顯示,形式基本如下
# 修改字段名
select column_name AS new_name from table_name;
# 修改表名
select abc.column_name from table_name AS abc;
select * from table_name AS abc where abc.column_name = ···;
修改表名多爲了編寫sql語句時遇到過長表名,簡化用的,而且一般多用於多表查詢時(多表查詢需要用表名來標記字段)
修改列名可能爲了簡化,也可能爲了按照要求改變輸出內容,如
mysql> select sum(point) from test;
+------------+
| sum(point) |
+------------+
| 650 |
+------------+
mysql> select sum(point) as "總分" from test;
+--------+
| 總分 |
+--------+
| 650 |
+--------+
當時用某些函數對字段進行處理之後,返回的是一個新的字段,該字段會用SQL語句中的對應函數調用結構作爲字段名,如果對返回字段名有要求就可以用 AS 進行修改
9.having
having單獨使用類似於where的用法,現有下面這張表格test,要獲取分數大於95的人的信息
mysql> select * from test;
+------+---------+-------+
| name | subject | score |
+------+---------+-------+
| a | English | 100 |
| b | Math | 95 |
| c | English | 90 |
| d | Chinese | 90 |
| e | Math | 92 |
| f | English | 97 |
+------+---------+-------+
mysql> select * from test having score > 95;
+------+---------+-------+
| name | subject | score |
+------+---------+-------+
| a | English | 100 |
| f | English | 97 |
+------+---------+-------+
having關鍵字一般配合group by使用。
要獲取表格中出現重複的學科,肉眼可見是“English” 和 “Math”,可以這樣獲取
mysql> select subject from test group by subject having count(subject) > 1;
+---------+
| subject |
+---------+
| English |
| Math |
+---------+
先用group by對學科字段進行分組,然後用having對結果進行篩選,取出數量大於1的學科,即重複的學科
需要注意的是,這裏的having不可以用where來代替,因爲優先級的關係,where需要在group by的前面。如果爲了沒有語法錯誤將where放在前面,語句的邏輯就會出現問題,或者出現新的錯誤。
注:關於優先級,where > group by > having > order by
10.in/not in
顧名思義,就是判斷 在(不在) 字段 裏面,具體用法如下
現有表格test和test2,要找出(未)在test2表格中登記的人的name
mysql> select * from test;
+------+---------+-------+
| name | subject | score |
+------+---------+-------+
| a | English | 100 |
| b | Math | 95 |
| c | English | 90 |
| d | Chinese | 90 |
| e | Math | 92 |
| f | English | 97 |
+------+---------+-------+
mysql> select * from test2;
+------+------+
| id | name |
+------+------+
| 1 | a |
| 2 | c |
| 3 | e |
+------+------+
mysql> select name from test where name in (select name from test2);
+------+
| name |
+------+
| a |
| c |
| e |
+------+
mysql> select name from test where name not in (select name from test2);
+------+
| name |
+------+
| b |
| d |
| f |
+------+