資料庫MySQL-查詢語句

  • 2020 年 3 月 27 日
  • 筆記

1.5 查詢語句

語法:select [選項] 列名 [from 表名] [where 條件]  [group by 分組] [order by 排序][having 條件] [limit 限制]

1.5.1 欄位表達式

-- 可以直接輸出內容  mysql> select '鋤禾日當午';  +------------+  | 鋤禾日當午          |  +------------+  | 鋤禾日當午          |  +------------+  1 row in set (0.00 sec)    -- 輸出表達式  mysql> select 10*10;  +-------+  | 10*10 |  +-------+  |   100 |  +-------+  1 row in set (0.00 sec)    mysql> select ch,math,ch+math from stu;  +------+------+---------+  | ch   | math | ch+math |  +------+------+---------+  |   80 | NULL |    NULL |  |   77 |   76 |     153 |  |   55 |   82 |     137 |  | NULL |   74 |    NULL |      -- 表達式部分可以用函數  mysql> select rand();  +--------------------+  | rand()             |  +--------------------+  | 0.6669325378415478 |  +--------------------+  1 row in set (0.00 sec)

通過as給欄位取別名

mysql> select '鋤禾日當午' as '標題';   -- 取別名  +------------+  | 標題           |  +------------+  | 鋤禾日當午          |  +------------+  1 row in set (0.00 sec)    mysql> select ch,math,ch+math as '總分' from stu;  +------+------+------+  | ch   | math | 總分    |  +------+------+------+  |   80 | NULL | NULL |  |   77 |   76 |  153 |  |   55 |   82 |  137 |  | NULL |   74 | NULL |    -- 多學一招:as可以省略  mysql> select ch,math,ch+math '總分' from stu;  +------+------+------+  | ch   | math | 總分    |  +------+------+------+  |   80 | NULL | NULL |  |   77 |   76 |  153 |  |   55 |   82 |  137 |  | NULL |   74 | NULL |

1.5.2 from子句

from:來自,from後面跟的是數據源。數據源可以有多個。返回笛卡爾積。

插入測試表

create table t1(         str char(2)  );  insert into t1 values ('aa'),('bb');  create table t2(         num int  );  insert into t2 values (10),(20);

測試

-- from子句  mysql> select * from t1;  +------+  | str  |  +------+  | aa   |  | bb   |  +------+  2 rows in set (0.00 sec)    -- 多個數據源,返回笛卡爾積  mysql> select * from t1,t2;  +------+------+  | str  | num  |  +------+------+  | aa   |   10 |  | bb   |   10 |  | aa   |   20 |  | bb   |   20 |  +------+------+  4 rows in set (0.00 sec)

1.5.3 dual表

dual表是一個偽表。在有些特定情況下,沒有具體的表的參與,但是為了保證select語句的完整又必須要一個表名,這時候就使用偽表。

mysql> select 10*10 as 結果 from dual;  +------+  | 結果     |  +------+  |  100 |  +------+  1 row in set (0.00 sec)

1.5.4 where子句

where後面跟的是條件,在數據源中進行篩選。返回條件為真記錄

MySQL支援的運算符

-- 比較運算符  >	大於  <	小於  >=	大於等於  <=	小於等於  =	等於  !=	不等於  -- 邏輯運算符  and  與  or   或  not  非  -- 其他  in | not in	 					 欄位的值在枚舉範圍內  between…and|not between…and      欄位的值在數字範圍內  is null | is not null			 欄位的值不為空

例題:

-- 查找語文成績及格的學生  mysql> select * from stu where ch>=60;  -- 查詢語文和數學都及格的學生  mysql> select * from stu where ch>=60 and math>=60;  -- 查詢語文或數學不及格的學生  mysql> select * from stu where ch<60 or math<60;

思考:如下語句輸出什麼?

mysql> select * from stu where 1;		-- 輸出所有數據  mysql> select * from stu where 0;		-- 不輸出數據

思考:如何查找北京和上海的學生

-- 通過or實現  mysql> select * from stu where stuaddress='北京' or stuaddress='上海';    -- 通過in語句實現  mysql> select * from stu where stuaddress in ('北京','上海');    -- 查詢不是北京和上海的學生  mysql> select * from stu where stuaddress not in ('北京','上海');

思考:查找年齡在20~25之間

-- 方法一:  mysql> select * from stu where stuage>=20 and stuage<=25;    -- 方法二:  mysql> select * from stu where not(stuage<20 or stuage>25);    -- 方法三:between...and...  mysql> select * from stu where stuage between 20 and 25;    -- 年齡不在20~25之間  mysql> select * from stu where stuage not between 20 and 25;

思考:

-- 查找缺考的學生  mysql> select * from stu where ch is null or math is null;  +--------+----------+--------+--------+---------+------------+------+------+  | stuNo  | stuName  | stuSex | stuAge | stuSeat | stuAddress | ch   | math |  +--------+----------+--------+--------+---------+------------+------+------+  | s25301 | 張秋麗         | 男       |     18 |       1 | 北京           |   80 | NULL |  | s25304 | 歐陽俊雄        | 男       |     28 |       4 | 天津           | NULL |   74 |  +--------+----------+--------+--------+---------+------------+------+------+    -- 查找沒有缺考的學生  mysql> select * from stu where ch is not null and math is not null;  +--------+----------+--------+--------+---------+------------+------+------+  | stuNo  | stuName  | stuSex | stuAge | stuSeat | stuAddress | ch   | math |  +--------+----------+--------+--------+---------+------------+------+------+  | s25302 | 李文才        | 男       |     31 |       3 | 上海          |   77 |   76 |  | s25303 | 李斯文        | 女      |     22 |       2 | 北京           |   55 |   82 |  | s25305 | 諸葛麗麗         | 女      |     23 |       7 | 河南           |   72 |   56 |  | s25318 | 爭青小子        | 男       |     26 |       6 | 天津           |   86 |   92 |  | s25319 | 梅超風        | 女      |     23 |       5 | 河北          |   74 |   67 |  | s25320 | Tom      | 男       |     24 |       8 | 北京           |   65 |   67 |  | s25321 | Tabm     | 女      |     23 |       9 | 河北          |   88 |   77 |  +--------+----------+--------+--------+---------+------------+------+------+  7 rows in set (0.00 sec)    -- 查找需要補考的學生  mysql> select * from stu where ch<60 or math<60 or ch is null or math is null;  +--------+----------+--------+--------+---------+------------+------+------+  | stuNo  | stuName  | stuSex | stuAge | stuSeat | stuAddress | ch   | math |  +--------+----------+--------+--------+---------+------------+------+------+  | s25301 | 張秋麗         | 男       |     18 |       1 | 北京           |   80 | NULL |  | s25303 | 李斯文        | 女      |     22 |       2 | 北京           |   55 |   82 |  | s25304 | 歐陽俊雄        | 男       |     28 |       4 | 天津           | NULL |   74 |  | s25305 | 諸葛麗麗         | 女      |     23 |       7 | 河南           |   72 |   56 |  +--------+----------+--------+--------+---------+------------+------+------+  4 rows in set (0.00 sec)

練習:

-- 1、查找學號是s25301,s25302,s25303的學生  mysql> select * from stu where stuno in ('s25301','s25302','s25303');  +--------+---------+--------+--------+---------+------------+------+------+  | stuNo  | stuName | stuSex | stuAge | stuSeat | stuAddress | ch   | math |  +--------+---------+--------+--------+---------+------------+------+------+  | s25301 | 張秋麗        | 男       |     18 |       1 | 北京           |   80 | NULL |  | s25302 | 李文才       | 男       |     31 |       3 | 上海          |   77 |   76 |  | s25303 | 李斯文       | 女      |     22 |       2 | 北京           |   55 |   82 |  +--------+---------+--------+--------+---------+------------+------+------+  3 rows in set (0.00 sec)    -- 2、查找年齡是18~20的學生  mysql> select * from stu where stuage between 18 and 20;  +--------+---------+--------+--------+---------+------------+------+------+  | stuNo  | stuName | stuSex | stuAge | stuSeat | stuAddress | ch   | math |  +--------+---------+--------+--------+---------+------------+------+------+  | s25301 | 張秋麗        | 男       |     18 |       1 | 北京           |   80 | NULL |  +--------+---------+--------+--------+---------+------------+------+------+  1 row in set (0.00 sec)

1.5.5 group by 【分組查詢】

將查詢的結果分組,分組查詢目的在於統計數據。

-- 查詢男生和女生的各自語文平均分  mysql> select stusex,avg(ch) '平均分' from stu group by stusex;  +--------+---------+  | stusex | 平均分       |  +--------+---------+  | 女      | 72.2500 |  | 男       | 77.0000 |  +--------+---------+  2 rows in set (0.00 sec)    -- 查詢男生和女生各自多少人  mysql> select stusex,count(*) 人數 from stu group by stusex;  +--------+------+  | stusex | 人數     |  +--------+------+  | 女      |    4 |  | 男       |    5 |  +--------+------+  2 rows in set (0.00 sec)    -- 查詢每個地區多少人  mysql> select stuaddress,count(*) from stu group by stuaddress;  +------------+----------+  | stuaddress | count(*) |  +------------+----------+  | 上海          |        1 |  | 北京           |        3 |  | 天津           |        2 |  | 河北          |        2 |  | 河南           |        1 |  +------------+----------+  5 rows in set (0.00 sec)    -- 每個地區的數學平均分  mysql> select stuaddress,avg(math) from stu group by stuaddress;  +------------+-----------+  | stuaddress | avg(math) |  +------------+-----------+  | 上海          |   76.0000 |  | 北京           |   74.5000 |  | 天津           |   83.0000 |  | 河北          |   72.0000 |  | 河南           |   56.0000 |  +------------+-----------+  5 rows in set (0.00 sec)

查詢欄位是普通欄位,只取第一個值

通過group_concat()函數將同一組的值連接起來顯示

mysql> select group_concat(stuname),stusex,avg(math) from stu group by stusex;  +-------------------------------------+--------+-----------+  | group_concat(stuname)               | stusex | avg(math) |  +-------------------------------------+--------+-----------+  | 李斯文,諸葛麗麗,梅超風,Tabm             | 女      |   70.5000 |  | 張秋麗,李文才,歐陽俊雄,爭青小子,Tom      | 男       |   77.2500 |  +-------------------------------------+--------+-----------+  2 rows in set (0.00 sec)

多列分組

mysql> select stuaddress,stusex,avg(math) from stu group by stuaddress,stusex;  +------------+--------+-----------+  | stuaddress | stusex | avg(math) |  +------------+--------+-----------+  | 上海          | 男       |   76.0000 |  | 北京           | 女      |   82.0000 |  | 北京           | 男       |   67.0000 |  | 天津           | 男       |   83.0000 |  | 河北          | 女      |   72.0000 |  | 河南           | 女      |   56.0000 |  +------------+--------+-----------+  6 rows in set (0.00 sec)

小結:

1、如果是分組查詢,查詢欄位是分組欄位和聚合函數。  2、查詢欄位是普通欄位,只取第一個值  3、group_concat()將同一組的數據連接起來

1.5.6 order by排序

asc:升序【默認】

desc:降序

-- 按年齡的升序排列  mysql> select * from stu order by stuage asc;  mysql>  select * from stu order by stuage;       -- 默認是升序    -- 按總分降序  mysql> select *,ch+math '總分' from stu order by ch+math desc;

多列排序

-- 年齡升序,如果年齡一樣,按ch降序排列  mysql> select * from stu order by stuage asc,ch desc;

思考如下程式碼表示什麼含義

select * from stu order by stuage desc,ch desc;     #年齡降序,語文降序  select * from stu order by stuage desc,ch asc;		#年齡降序,語文升序  select * from stu order by stuage,ch desc;          #年齡升序、語文降序  select * from stu order by stuage,ch; 				#年齡升序、語文升序

1.5.7 having條件

having:是在結果集上進行條件篩選

例題

-- 查詢女生  mysql> select * from stu where stusex='女';  +--------+----------+--------+--------+---------+------------+------+------+  | stuNo  | stuName  | stuSex | stuAge | stuSeat | stuAddress | ch   | math |  +--------+----------+--------+--------+---------+------------+------+------+  | s25303 | 李斯文        | 女      |     22 |       2 | 北京           |   55 |   82 |  | s25305 | 諸葛麗麗         | 女      |     23 |       7 | 河南           |   72 |   56 |  | s25319 | 梅超風        | 女      |     23 |       5 | 河北          |   74 |   67 |  | s25321 | Tabm     | 女      |     23 |       9 | 河北          |   88 |   77 |  +--------+----------+--------+--------+---------+------------+------+------+  4 rows in set (0.00 sec)    -- 查詢女生  mysql> select * from stu having stusex='女';  +--------+----------+--------+--------+---------+------------+------+------+  | stuNo  | stuName  | stuSex | stuAge | stuSeat | stuAddress | ch   | math |  +--------+----------+--------+--------+---------+------------+------+------+  | s25303 | 李斯文        | 女      |     22 |       2 | 北京           |   55 |   82 |  | s25305 | 諸葛麗麗         | 女      |     23 |       7 | 河南           |   72 |   56 |  | s25319 | 梅超風        | 女      |     23 |       5 | 河北          |   74 |   67 |  | s25321 | Tabm     | 女      |     23 |       9 | 河北          |   88 |   77 |  +--------+----------+--------+--------+---------+------------+------+------+  4 rows in set (0.00 sec)    -- 查詢女生姓名  mysql> select stuname from stu where stusex='女';  +----------+  | stuname  |  +----------+  | 李斯文        |  | 諸葛麗麗         |  | 梅超風        |  | Tabm     |  +----------+  4 rows in set (0.00 sec)    -- 使用having報錯,因為結果集中沒有stusex欄位  mysql> select stuname from stu having stusex='女';  ERROR 1054 (42S22): Unknown column 'stusex' in 'having clause'

小結:having和where的區別:

where是對原始數據進行篩選,having是對記錄集進行篩選。

1.5.8 limit

語法:limit [起始位置],顯示長度

-- 從第0個位置開始取,取3條記錄  mysql> select * from stu limit 0,3;    -- 從第2個位置開始取,取3條記錄  mysql> select * from stu limit 2,3;  +--------+----------+--------+--------+---------+------------+------+------+  | stuNo  | stuName  | stuSex | stuAge | stuSeat | stuAddress | ch   | math |  +--------+----------+--------+--------+---------+------------+------+------+  | s25303 | 李斯文        | 女      |     22 |       2 | 北京           |   55 |   82 |  | s25304 | 歐陽俊雄        | 男       |     28 |       4 | 天津           | NULL |   74 |  | s25305 | 諸葛麗麗         | 女      |     23 |       7 | 河南           |   72 |   56 |  +--------+----------+--------+--------+---------+------------+------+------+  3 rows in set (0.00 sec)

起始位置可以省略,默認是從0開始

mysql> select * from stu limit 3;  +--------+---------+--------+--------+---------+------------+------+------+  | stuNo  | stuName | stuSex | stuAge | stuSeat | stuAddress | ch   | math |  +--------+---------+--------+--------+---------+------------+------+------+  | s25301 | 張秋麗        | 男       |     18 |       1 | 北京           |   80 | NULL |  | s25302 | 李文才       | 男       |     31 |       3 | 上海          |   77 |   76 |  | s25303 | 李斯文       | 女      |     22 |       2 | 北京           |   55 |   82 |  +--------+---------+--------+--------+---------+------------+------+------+  3 rows in set (0.00 sec)

例題:找出班級總分前三名

mysql> select *,ch+math total from stu order by (ch+math) desc limit 0,3;  +--------+----------+--------+--------+---------+------------+------+------+-------+  | stuNo  | stuName  | stuSex | stuAge | stuSeat | stuAddress | ch   | math | total |  +--------+----------+--------+--------+---------+------------+------+------+-------+  | s25318 | 爭青小子   | 男       |     26 |       6 | 天津           |   86 |   92 |   178 |  | s25321 | Tabm     | 女      |     23 |       9 | 河北          |   88 |   77 |   165 |  | s25302 | 李文才    | 男       |     31 |       3 | 上海          |   77 |   76 |   153 |  +--------+----------+--------+--------+---------+------------+------+------+-------+  3 rows in set (0.00 sec)

多學一招:limit在update和delete語句中也是可以使用的。

-- 	前3名語文成績加1分  mysql> update stu set ch=ch+1 order by ch+math desc limit 3;  Query OK, 3 rows affected (0.00 sec)  Rows matched: 3  Changed: 3  Warnings: 0    -- 前3名刪除  mysql> delete from stu order by ch+math desc limit 3;  Query OK, 3 rows affected (0.00 sec)

1.5.9 查詢語句中的選項

查詢語句中的選項有兩個:

1、 all:顯示所有數據 【默認】

2、 distinct:去除結果集中重複的數據

mysql> select all stuaddress from stu;  +------------+  | stuaddress |  +------------+  | 北京           |  | 北京           |  | 天津           |  | 河南           |  | 河北          |  | 北京           |  +------------+  6 rows in set (0.00 sec)    -- 去除重複的項  mysql> select distinct stuaddress from stu;  +------------+  | stuaddress |  +------------+  | 北京           |  | 天津           |  | 河南           |  | 河北          |  +------------+  4 rows in set (0.00 sec)