1. 程式人生 > 實用技巧 >MySQL 查詢語句

MySQL 查詢語句

MySQL 查詢語句

查詢單表查詢多表查詢DQLSELECTSHOWWHEREGROUP BYHAVINGORDER BYLIMITASUNIONUNION ALLDISTINCT

歡迎來到 來到大浪濤天的部落格

一、MySQL 查詢語句

1. DQL 介紹

MySQL 最多的操作就是查詢,搜尋資料,因此查詢語句非常重要,怎樣查詢效率最高,代價最低,值得好好商榷。
如何快速熟悉資料庫業務:

  1. 快速和研發人員打好關係
  2. 找到領導要ER圖
  3. DESC ,show create table
  4. select * from city limit 5;
    查詢語句主要分以下兩種:
  • select
  • show

2. select 語句的應用

2-1. select單獨使用的情況,不針對任何資料庫,檢視MySQL的具體引數配置情況

mysql> select @@basedir;
mysql> select @@port;
mysql> select @@innodb_flush_log_at_trx_commit;
mysql> show variables;(檢視所有引數)
mysql> show variables like 'innodb%';
mysql> select database();
mysql> select now();

2-2. select 通用語法(單表)

單表查詢的語句執行順序如下:

select  列   
from  表   
where 條件  
group by  條件 
having   條件 
order by 條件
limit

2-3. 具體查詢例項如下

2-3-1. 學習環境的說明
  1. world資料庫
city           	 城市表
country          國家表  
countrylanguage  國家的語言
  1. city表結構
mysql> desc city;
+-------------+----------+------+-----+---------+----------------+
| Field       | Type     | Null | Key | Default | Extra          |
+-------------+----------+------+-----+---------+----------------+
| ID          | int(11)  | NO   | PRI | NULL    | auto_increment |
| Name        | char(35) | NO   |     |         |                |
| CountryCode | char(3)  | NO   | MUL |         |                |
| District    | char(20) | NO   |     |         |                |
| Population  | int(11)  | NO   |     | 0       |                |
+-------------+----------+------+-----+---------+----------------+

5 rows in set (0.00 sec)
  1. 各個欄位的備註如下:
mysql> 

ID  		:  	城市序號(1-...)
name		: 	城市名字
countrycode :   國家程式碼,例如:CHN,USA
district    :   區域: 中國 省  美國 洲
population  :   人口數
2-3-2. SELECT 配合 FROM 子句使用
  1. 語法如下
select  列,列,列  from  表
1. 查詢表中所有的資訊(生產中幾乎是沒有這種需求的)
USE world ;
SELECT  id,NAME ,countrycode ,district,population   FROM  city;
或者:
SELECT  *   FROM city;

2. 查詢表中 name和population的值
SELECT  NAME ,population   FROM  city;
  1. SELECT 配合 WHERE 子句使用
-- select  列,列,列  from  表  where 過濾條件
-- where等值條件查詢  

例如:

  • 查詢中國所有的城市名和人口數
mysql> SELECT Name,Population FROM city WHERE CountryCode='CHN' limit 3;
+-----------+------------+
| Name      | Population |
+-----------+------------+
| Shanghai  |    9696300 |
| Peking    |    7472000 |
| Chongqing |    6351600 |
+-----------+------------+
  1. where 配合比較判斷查詢(> < >= <=) *****
    例如:
  • 世界上小於100人的城市名和人口數
mysql> SELECT Name,Population FROM city WHERE Population<100;
+-----------+------------+
| Name      | Population |
+-----------+------------+
| Adamstown |         42 |
+-----------+------------+
1 row in set (0.01 sec)
  1. where 配合 邏輯連線符(and or)
    例如:
  • 查詢中國人口數量大於800w的城市名和人口
mysql> SELECT Name,Population FROM city WHERE Countrycode='CHN' AND Population>8000000;   
+----------+------------+
| Name     | Population |
+----------+------------+
| Shanghai |    9696300 |
+----------+------------+
1 row in set (0.00 sec)
  • 查詢中國或美國的城市名和人口數
mysql> SELECT Name,Population FROM city WHERE Countrycode='CHN' OR Countrycode='USA' limit 3;
+-----------+------------+
| Name      | Population |
+-----------+------------+
| Shanghai  |    9696300 |
| Peking    |    7472000 |
| Chongqing |    6351600 |
+-----------+------------+
3 rows in set (0.00 sec)
  • 查詢人口數量在500w到600w之間的城市名和人口數
mysql> SELECT Name,Population FROM city WHERE Population >5000000 AND Population<6000000;
+----------------+------------+
| Name           | Population |
+----------------+------------+
| Rio de Janeiro |    5598953 |
| Tianjin        |    5286800 |
| Kinshasa       |    5064000 |
| Lahore         |    5063499 |
+----------------+------------+
4 rows in set (0.00 sec)

或者用BETWEEN來匹配

mysql> SELECT Name,Population FROM city WHERE Population BETWEEN 5000000 AND 6000000;
+----------------+------------+
| Name           | Population |
+----------------+------------+
| Rio de Janeiro |    5598953 |
| Tianjin        |    5286800 |
| Kinshasa       |    5064000 |
| Lahore         |    5063499 |
+----------------+------------+
  1. where 配合 like 子句 模糊查詢
    例如:查詢一下contrycode中帶有CH開頭的城市資訊
mysql> SELECT * FROM city WHERE Countrycode LIKE 'CH%' limit 3;
+------+---------+-------------+-------------+------------+
| ID   | Name    | CountryCode | District    | Population |
+------+---------+-------------+-------------+------------+
| 3245 | Zürich  | CHE         | Zürich      |     336800 |
| 3246 | Geneve  | CHE         | Geneve      |     173500 |
| 3247 | Basel   | CHE         | Basel-Stadt |     166700 |
+------+---------+-------------+-------------+------------+

注意:不要出現類似於 %CH%,前後都有百分號的語句,因為不走索引,效能極差,如果業務中有大量需求,我們用"ES"來替代.
6. where 配合 in 語句
例如:查詢中國或美國的城市資訊.

mysql> SELECT * FROM city WHERE Countrycode IN ('CHN','USA') limit 3;
+------+-----------+-------------+-----------+------------+
| ID   | Name      | CountryCode | District  | Population |
+------+-----------+-------------+-----------+------------+
| 1890 | Shanghai  | CHN         | Shanghai  |    9696300 |
| 1891 | Peking    | CHN         | Peking    |    7472000 |
| 1892 | Chongqing | CHN         | Chongqing |    6351600 |
+------+-----------+-------------+-----------+------------+
3 rows in set (0.01 sec)
或者
mysql> SELECT * FROM city WHERE Countrycode='CHN' OR Countrycode='USA' limit 3;
+------+-----------+-------------+-----------+------------+
| ID   | Name      | CountryCode | District  | Population |
+------+-----------+-------------+-----------+------------+
| 1890 | Shanghai  | CHN         | Shanghai  |    9696300 |
| 1891 | Peking    | CHN         | Peking    |    7472000 |
| 1892 | Chongqing | CHN         | Chongqing |    6351600 |
+------+-----------+-------------+-----------+------------+
3 rows in set (0.00 sec)
2-3-3. SELECT配合WHERE及GROUP BY語句

將某列中有共同條件的資料行,分成一組,然後在進行聚合函式操作.
例如以下語句:

  1. 統計每個國家,城市的個數
mysql> SELECT Countrycode,count(ID) FROM city GROUP BY Countrycode limit 3;
+-------------+-----------+
| Countrycode | count(ID) |
+-------------+-----------+
| ABW         |         1 |
| AFG         |         4 |
| AGO         |         5 |
+-------------+-----------+
  1. 統計每個國家的總人口數.
mysql> SELECT Countrycode,SUM(Population) FROM city GROUP BY Countrycode limit 3;
+-------------+-----------------+
| Countrycode | SUM(Population) |
+-------------+-----------------+
| ABW         |           29034 |
| AFG         |         2332100 |
| AGO         |         2561600 |
+-------------+-----------------+
  1. 統計中國省的個數
mysql> SELECT CountryCode,COUNT(DISTINCT District) FROM city WHERE CountryCode='CHN' GROUP BY CountryCode;  
+-------------+--------------------------+
| CountryCode | COUNT(DISTINCT District) |
+-------------+--------------------------+
| CHN         |                       31 |
+-------------+--------------------------+
1 row in set (0.00 sec)
  1. 統計中國 每個省的總人口數
mysql> SELECT District,SUM(Population) FROM city
    -> WHERE CountryCode='CHN'
    -> GROUP BY District
    -> limit 3;
+-----------+-----------------+
| District  | SUM(Population) |
+-----------+-----------------+
| Anhui     |         5141136 |
| Chongqing |         6351600 |
| Fujian    |         3575650 |
+-----------+-----------------+
  1. 統計中國 每個省城市的個數
mysql> SELECT district,COUNT(ID) FROM city
    -> WHERE countrycode='CHN'
    -> GROUP BY district
    -> limit 3;
+-----------+-----------+
| district  | COUNT(ID) |
+-----------+-----------+
| Anhui     |        16 |
| Chongqing |         1 |
| Fujian    |        12 |
+-----------+-----------+
  1. 統計中國每個省城市的名字列表GROUP_CONCAT()
    guangdong guangzhou,shenzhen,foshan....
mysql> SELECT district,GROUP_CONCAT(Name) FROM city
    -> WHERE countrycode='CHN'
    -> GROUP BY district
    -> limit 3;
+-----------+------------------------------------------------------------------------------------------------------------------------------+
| district  | GROUP_CONCAT(Name)                                                                                                           |
+-----------+------------------------------------------------------------------------------------------------------------------------------+
| Anhui     | Hefei,Huainan,Bengbu,Wuhu,Huaibei,Ma´anshan,Anqing,Tongling,Fuyang,Suzhou,Liu´an,Chuzhou,Chaohu,Xuangzhou,Bozhou,Huangshan   |
| Chongqing | Chongqing                                                                                                                    |
| Fujian    | Fuzhou,Amoy [Xiamen],Nanping,Quanzhou,Zhangzhou,Sanming,Longyan,Yong´an,Fu´an,Fuqing,Putian,Shaowu                           |
+-----------+------------------------------------------------------------------------------------------------------------------------------+
  1. 擴充套件統計中國每個省城市的名字列表,按下列要求展現出來
    anhui : hefei,huaian ....
mysql> SELECT CONCAT(district,":",GROUP_CONCAT(Name)) FROM city
    -> WHERE countrycode='CHN'
    -> GROUP BY district
    -> limit 3;
+------------------------------------------------------------------------------------------------------------------------------------+
| CONCAT(district,":",GROUP_CONCAT(Name))                                                                                            |
+------------------------------------------------------------------------------------------------------------------------------------+
| Anhui:Hefei,Huainan,Bengbu,Wuhu,Huaibei,Ma´anshan,Anqing,Tongling,Fuyang,Suzhou,Liu´an,Chuzhou,Chaohu,Xuangzhou,Bozhou,Huangshan   |
| Chongqing:Chongqing                                                                                                                |
| Fujian:Fuzhou,Amoy [Xiamen],Nanping,Quanzhou,Zhangzhou,Sanming,Longyan,Yong´an,Fu´an,Fuqing,Putian,Shaowu                          |
+------------------------------------------------------------------------------------------------------------------------------------+
2-3-4. SELECT 配合 ORDER BY 子句

ORDER BY子句會自動將上述語句排序,預設是從小到大排序,如果加上DESC後會從大到小排序。另外如果在GROUP BY分組後的資料統計過濾不能使用WHERE來過濾了,必須使用HAVING(功能和WHERE是一致的,但是擺放順序不一樣)
例如:統計所有國家的總人口數量,將總人口數大於5000w的過濾出來,並且按照從小到大順序排列

mysql> SELECT countrycode,SUM(population) FROM city
    -> GROUP BY countrycode
    -> HAVING SUM(population)>50000000
    -> ORDER BY SUM(population) 
    -> LIMIT 10;
+-------------+-----------------+
| countrycode | SUM(population) |
+-------------+-----------------+
| MEX         |        59752521 |
| RUS         |        69150700 |
| JPN         |        77965107 |
| USA         |        78625774 |
| BRA         |        85876862 |
| IND         |       123298526 |
| CHN         |       175953614 |
+-------------+-----------------+
2-3-5. SELECT 配合 LIMIT 子句

LIMIT的優先順序最低,所以擺放在最後,功能是限制列印的行數,OFFSET是指偏離,OFFSET為0時只不偏離。
LIMIT M,N :跳過M行,顯示一共N行
LIMIT Y OFFSET X: 跳過X行,顯示一共Y行
例如:

  1. 統計所有國家的總人口數量,將總人口數大於5000w的過濾出來,並且按照從大到小順序排列,只顯示前三名
SELECT countrycode,SUM(population) FROM city
GROUP BY countrycode
HAVING SUM(population)>50000000
ORDER BY SUM(population) DESC 
LIMIT 3 OFFSET 0;

如果現實四到六名,則可以採用OFFSET 3來實現,意思是limit3到了3行後再向後面偏離3行,前面的不顯示,就正好是四五六名,如下:

mysql> SELECT countrycode,SUM(population) FROM city 
    -> GROUP BY countrycode
    -> HAVING SUM(population)>5000000
    -> ORDER BY SUM(population) DESC
    -> LIMIT 3 OFFSET 3;
+-------------+-----------------+
| countrycode | SUM(population) |
+-------------+-----------------+
| USA         |        78625774 |
| JPN         |        77965107 |
| RUS         |        69150700 |
+-------------+-----------------+
  1. 統計中國每個省的總人口數,只打印總人口數小於100w的
mysql> SELECT district,SUM(population) FROM city 
    -> WHERE countrycode='CHN'
    -> GROUP BY district
    -> HAVING SUM(population) <1000000;
+----------+-----------------+
| district | SUM(population) |
+----------+-----------------+
| Hainan   |          557120 |
| Ningxia  |          802362 |
| Qinghai  |          700200 |
| Tibet    |          120000 |
+----------+-----------------+
  1. 檢視中國所有的城市,並按人口數進行排序(從大到小)
mysql> SELECT name,population FROM city
    -> WHERE countrycode='CHN'
    -> ORDER BY population DESC;
+---------------------+------------+
| name                | population |
+---------------------+------------+
| Shanghai            |    9696300 |
| Peking              |    7472000 |
| Chongqing           |    6351600 |
| Tianjin             |    5286800 |
  1. 統計中國各個省的總人口數量,按照總人口從大到小排序
mysql> SELECT district,SUM(population) FROM city
    -> WHERE countrycode='CHN'
    -> GROUP BY district
    -> ORDER BY SUM(population) DESC;
+----------------+-----------------+
| district       | SUM(population) |
+----------------+-----------------+
| Liaoning       |        15079174 |
| Shandong       |        12114416 |
| Heilongjiang   |        11628057 |
| Jiangsu        |         9719860 |
  1. 統計中國,每個省的總人口,找出總人口大於500w的,
    並按總人口從大到小排序,只顯示前三名
mysql> SELECT district,SUM(population) FROM city
    -> WHERE countrycode='CHN'
    -> GROUP BY district
    -> HAVING SUM(population)>5000000
    -> ORDER BY SUM(population) DESC
    -> LIMIT 3;
+--------------+-----------------+
| district     | SUM(population) |
+--------------+-----------------+
| Liaoning     |        15079174 |
| Shandong     |        12114416 |
| Heilongjiang |        11628057 |
+--------------+-----------------+
2-3-6. union 和 union all

作用: 多個結果集合並查詢的功能,常用語語句改寫,因為OR和IN效能太差了
union all 不做去重複
union 會做去重操作
例如:查詢中或者美國的城市資訊

mysql> SELECT * FROM city WHERE countrycode='CHN' UNION ALL SELECT * FROM city WHERE countrycode='USA' LIMIT 3;
+------+-----------+-------------+-----------+------------+
| ID   | Name      | CountryCode | District  | Population |
+------+-----------+-------------+-----------+------------+
| 1890 | Shanghai  | CHN         | Shanghai  |    9696300 |
| 1891 | Peking    | CHN         | Peking    |    7472000 |
| 1892 | Chongqing | CHN         | Chongqing |    6351600 |
+------+-----------+-------------+-----------+------------+

mysql> DESC SELECT * FROM city WHERE countrycode='CHN' OR countrycode='USA' LIMIT 3;
+----+-------------+-------+------------+-------+---------------+-------------+---------+------+------+----------+-----------------------+
| id | select_type | table | partitions | type  | possible_keys | key         | key_len | ref  | rows | filtered | Extra                 |
+----+-------------+-------+------------+-------+---------------+-------------+---------+------+------+----------+-----------------------+
|  1 | SIMPLE      | city  | NULL       | range | CountryCode   | CountryCode | 3       | NULL |  637 |   100.00 | Using index condition |
+----+-------------+-------+------------+-------+---------------+-------------+---------+------+------+----------+-----------------------+
1 row in set, 1 warning (0.00 sec)


mysql>  SELECT * FROM city WHERE countrycode='CHN' UNION ALL SELECT * FROM city WHERE countrycode='USA' LIMIT 3;    
+------+-----------+-------------+-----------+------------+
| ID   | Name      | CountryCode | District  | Population |
+------+-----------+-------------+-----------+------------+
| 1890 | Shanghai  | CHN         | Shanghai  |    9696300 |
| 1891 | Peking    | CHN         | Peking    |    7472000 |
| 1892 | Chongqing | CHN         | Chongqing |    6351600 |
+------+-----------+-------------+-----------+------------+

mysql> DESC SELECT * FROM city WHERE countrycode='CHN' UNION ALL SELECT * FROM city WHERE countrycode='USA' LIMIT 3;
+----+-------------+-------+------------+------+---------------+-------------+---------+-------+------+----------+-------+
| id | select_type | table | partitions | type | possible_keys | key         | key_len | ref   | rows | filtered | Extra |
+----+-------------+-------+------------+------+---------------+-------------+---------+-------+------+----------+-------+
|  1 | PRIMARY     | city  | NULL       | ref  | CountryCode   | CountryCode | 3       | const |  363 |   100.00 | NULL  |
|  2 | UNION       | city  | NULL       | ref  | CountryCode   | CountryCode | 3       | const |  274 |   100.00 | NULL  |
+----+-------------+-------+------------+------+---------------+-------------+---------+-------+------+----------+-------+
2-3-7. 多表連線查詢(內連線)

單表資料不能滿足查詢需求時.
例如下列學生成績統計資訊表查詢
查詢環境如下:

student :學生表
===============
sno:    學號
sname:學生姓名
sage: 學生年齡
ssex: 學生性別

teacher :教師表
================
tno:     教師編號
tname:教師名字

course :課程表
===============
cno:  課程編號
cname:課程名字
tno:  教師編號

score  :成績表
==============
sno:  學號
cno:  課程編號
score:成績

=====================
建立過程如下
=====================
mysql> create table student(
    -> sno int primary key not null default 0 auto_increment comment '學號',
    -> sname varchar(250) not null default 0 comment '學生姓名',
    -> sage tinyint not null default 0 comment '學生年齡',
    -> ssex enum('男','女','中') default '中' comment '學生性別')engine innodb charset utf8mb4 comment '學生表';
mysql> desc student;
+-------+-------------------------+------+-----+---------+----------------+
| Field | Type                    | Null | Key | Default | Extra          |
+-------+-------------------------+------+-----+---------+----------------+
| sno   | int(11)                 | NO   | PRI | NULL    | auto_increment |
| sname | varchar(250)            | NO   |     | 0       |                |
| sage  | tinyint(4)              | NO   |     | 0       |                |
| ssex  | enum('男','女','中')    | YES  |     | 中      |                |
+-------+-------------------------+------+-----+---------+----------------+

mysql> create table teacher(
    -> tno int primary key not null auto_increment comment '教師編號',
    -> tname varchar(250) not null default 0 comment '教師名字')engine innodb charset utf8mb4 comment '教師表';
Query OK, 0 rows affected (0.01 sec)
mysql> 
mysql> desc teacher;
+-------+--------------+------+-----+---------+----------------+
| Field | Type         | Null | Key | Default | Extra          |
+-------+--------------+------+-----+---------+----------------+
| tno   | int(11)      | NO   | PRI | NULL    | auto_increment |
| tname | varchar(250) | NO   |     | 0       |                |
+-------+--------------+------+-----+---------+----------------+
2 rows in set (0.01 sec)

mysql> create table course(
    -> cno int primary key not null auto_increment comment '課程編號',
    -> cname varchar(250) not null comment '課程名字',
    -> tno int not null comment '教師編號')engine innodb charset utf8mb4 comment '課程表';
Query OK, 0 rows affected (0.01 sec)

mysql> create table score(
    -> sno int not null comment '學生編號',
    -> cno int not null comment '課程編號',
    -> score int not null comment '學生成績')engine innodb charset utf8mb4 comment '成績表';
Query OK, 0 rows affected (0.01 sec)

mysql> desc course;
+-------+--------------+------+-----+---------+----------------+
| Field | Type         | Null | Key | Default | Extra          |
+-------+--------------+------+-----+---------+----------------+
| cno   | int(11)      | NO   | PRI | NULL    | auto_increment |
| cname | varchar(250) | NO   |     | NULL    |                |
| tno   | int(11)      | NO   |     | NULL    |                |
+-------+--------------+------+-----+---------+----------------+
3 rows in set (0.00 sec)

mysql> desc score;
+-------+---------+------+-----+---------+-------+
| Field | Type    | Null | Key | Default | Extra |
+-------+---------+------+-----+---------+-------+
| sno   | int(11) | NO   |     | NULL    |       |
| cno   | int(11) | NO   |     | NULL    |       |
| score | int(11) | NO   |     | NULL    |       |
+-------+---------+------+-----+---------+-------+

mysql> INSERT INTO student(sno,sname,sage,ssex) VALUES (1,'zhang3',18,'男');
mysql> INSERT INTO student(sno,sname,sage,ssex)
    -> VALUES
    -> (2,'zhang4',18,'男'),
    -> (3,'li4',18,'男'),
    -> (4,'wang5',19,'中');
Query OK, 3 rows affected (0.01 sec)
mysql> INSERT INTO student
    -> VALUES
    -> (5,'zh4',18,'男'),
    -> (6,'zhao4',18,'男'),
    -> (7,'ma6',19,'中');
Query OK, 3 rows affected (0.00 sec)
mysql> INSERT INTO student(sname,sage,ssex)
    -> VALUES
    -> ('oldboy',20,'男'),
    -> ('oldgirl',20,'女'),
    -> ('oldp',25,'女');
mysql> INSERT INTO teacher(tno,tname) VALUES
    -> (101,'oldboy'),
    -> (102,'hesw'),
    -> (103,'oldguo');
Query OK, 3 rows affected (0.00 sec)
mysql> INSERT INTO course(cno,cname,tno)
    -> VALUES
    -> (1001,'linux',101),
    -> (1002,'python',102),
    -> (1003,'mysql',103);
Query OK, 3 rows affected (0.01 sec)
Records: 3  Duplicates: 0  Warnings: 0
mysql> INSERT INTO score(sno,cno,score)
    -> VALUES
    -> (1,1001,80),
    -> (1,1002,59),
    -> (2,1002,90),
    -> (2,1003,100),
    -> (3,1001,99),
    -> (3,1003,40),
    -> (4,1001,79),
    -> (4,1002,61),
    -> (4,1003,99),
    -> (5,1003,40),
    -> (6,1001,89),
    -> (6,1003,77),
    -> (7,1001,67),
    -> (7,1003,82),
    -> (8,1001,70),
    -> (9,1003,80),
    -> (10,1003,96);
Query OK, 17 rows affected (0.00 sec)
mysql> select * from student;
+-----+---------+------+------+
| sno | sname   | sage | ssex |
+-----+---------+------+------+
|   1 | zhang3  |   18 | 男   |
|   2 | zhang4  |   18 | 男   |
|   3 | li4     |   18 | 男   |
|   4 | wang5   |   19 | 中   |
|   5 | zh4     |   18 | 男   |
|   6 | zhao4   |   18 | 男   |
|   7 | ma6     |   19 | 中   |
|   8 | oldboy  |   20 | 男   |
|   9 | oldgirl |   20 | 女   |
|  10 | oldp    |   25 | 女   |
+-----+---------+------+------+
mysql> select * from teacher;
+-----+--------+
| tno | tname  |
+-----+--------+
| 101 | oldboy |
| 102 | hesw   |
| 103 | oldguo |
+-----+--------+
3 rows in set (0.00 sec)
mysql> select * from course;
+------+--------+-----+
| cno  | cname  | tno |
+------+--------+-----+
| 1001 | linux  | 101 |
| 1002 | python | 102 |
| 1003 | mysql  | 103 |
+------+--------+-----+
3 rows in set (0.00 sec)
mysql> select * from score;
+-----+------+-------+
| sno | cno  | score |
+-----+------+-------+
|   1 | 1001 |    80 |
|   1 | 1002 |    59 |
|   2 | 1002 |    90 |
|   2 | 1003 |   100 |
|   3 | 1001 |    99 |
|   3 | 1003 |    40 |
|   4 | 1001 |    79 |
|   4 | 1002 |    61 |
|   4 | 1003 |    99 |
|   5 | 1003 |    40 |
|   6 | 1001 |    89 |
|   6 | 1003 |    77 |
|   7 | 1001 |    67 |
|   7 | 1003 |    82 |
|   8 | 1001 |    70 |
|   9 | 1003 |    80 |
|  10 | 1003 |    96 |
+-----+------+-------+
  1. 統計zhang3,學習了幾門課
mysql> SELECT student.sname,COUNT(score.cno) FROM student
    -> JOIN score ON student.sno=score.sno
    -> WHERE student.sname='zhang3';
+--------+------------------+
| sname  | COUNT(score.cno) |
+--------+------------------+
| zhang3 |                2 |
+--------+------------------+
1 row in set (0.01 sec)

-- 2. 查詢zhang3,學習的課程名稱有哪些?

mysql> SELECT student.sname,GROUP_CONCAT(course.cname) FROM student
    -> JOIN score ON student.sno=score.sno
    -> JOIN course ON score.cno=course.cno
    -> WHERE student.sname='zhang3'
    -> GROUP BY student.sname;
+--------+----------------------------+
| sname  | GROUP_CONCAT(course.cname) |
+--------+----------------------------+
| zhang3 | linux,python               |
+--------+----------------------------+

如果要串連方式顯示可以這樣:

mysql> SELECT CONCAT(student.sname,":",GROUP_CONCAT(course.cname)) FROM student
    -> JOIN score ON student.sno=score.sno
    -> JOIN course ON score.cno=course.cno
    -> WHERE student.sname='zhang3'
    -> GROUP BY student.sname;
+------------------------------------------------------+
| CONCAT(student.sname,":",GROUP_CONCAT(course.cname)) |
+------------------------------------------------------+
| zhang3:linux,python                                  |
+------------------------------------------------------+
1 row in set (0.02 sec)
  1. 查詢oldguo老師教的學生名和個數.
mysql> SELECT teacher.tname,GROUP_CONCAT(student.sname),count(student.sno) FROM teacher
    -> JOIN course ON teacher.tno=course.tno
    -> JOIN score ON course.cno=score.cno
    -> JOIN student ON score.sno=student.sno
    -> WHERE teacher.tname='oldguo'
    -> GROUP BY teacher.tname;
+--------+---------------------------------------------+------------------+
| tname  | GROUP_CONCAT(student.sname)                 | count(score.sno) |
+--------+---------------------------------------------+------------------+
| oldguo | zhang4,li4,wang5,zh4,zhao4,ma6,oldgirl,oldp |                8 |
+--------+---------------------------------------------+------------------+
  1. 查詢oldguo所教課程的平均分數
mysql> SELECT teacher.tname,AVG(score.score) FROM teacher
    -> JOIN course ON teacher.tno=course.tno
    -> JOIN score ON course.cno=score.cno
    -> WHERE teacher.tname='oldguo'
    -> GROUP BY teacher.tname;
+--------+------------------+
| tname  | AVG(score.score) |
+--------+------------------+
| oldguo |          76.7500 |
+--------+------------------+
  1. 每位老師所教課程的平均分,並按平均分排序
mysql> SELECT teacher.tname,AVG(score.score) FROM teacher 
    -> JOIN course ON teacher.tno=course.tno    
    -> JOIN score ON course.cno=score.cno
    -> GROUP BY teacher.tname;
+--------+------------------+
| tname  | AVG(score.score) |
+--------+------------------+
| hesw   |          70.0000 |
| oldboy |          80.6667 |
| oldguo |          76.7500 |
+--------+------------------+
  1. 查詢oldguo所教的不及格的學生姓名
mysql> SELECT teacher.tname,GROUP_CONCAT(student.sname) FROM teacher
    -> JOIN course ON teacher.tno=course.tno
    -> JOIN score ON course.cno=score.cno
    -> JOIN student ON score.sno=student.sno
    -> WHERE score.score <60
    -> AND teacher.tname='oldguo'
    -> GROUP BY teacher.tname;
+--------+-----------------------------+
| tname  | GROUP_CONCAT(student.sname) |
+--------+-----------------------------+
| oldguo | li4,zh4                     |
+--------+-----------------------------+
  1. 查詢lodguo所教不及格學生姓名及分數
mysql> SELECT teacher.tname,student.sname,score.score FROM teacher
    -> JOIN course ON teacher.tno=course.tno
    -> JOIN score ON course.cno=score.cno
    -> JOIN student ON score.sno=student.sno
    -> WHERE score.score <60
    -> AND teacher.tname='oldguo';

+--------+-------+-------+
| tname  | sname | score |
+--------+-------+-------+
| oldguo | li4   |    40 |
| oldguo | zh4   |    40 |
+--------+-------+-------+
  1. 查詢所有老師所教學生不及格的資訊
mysql> SELECT teacher.tname,GROUP_CONCAT(CONCAT(student.sname,":",score.score)) FROM teacher
    -> JOIN course ON teacher.tno=course.tno
    -> JOIN score ON course.cno=score.cno
    -> JOIN student ON score.sno=student.sno
    -> WHERE score.score <60
    -> GROUP BY teacher.tname;
+--------+-----------------------------------------------------+
| tname  | GROUP_CONCAT(CONCAT(student.sname,":",score.score)) |
+--------+-----------------------------------------------------+
| hesw   | zhang3:59                                           |
| oldguo | li4:40,zh4:40                                       |
+--------+-----------------------------------------------------+

注意:GROUP_CONCAT是分組後的整合,而CONCAT是直接串連,例如我們上面這個例子,我們要顯示出不及格同學的名字和分數,我們必須先把顯示個格式串聯出來,然後再分組整合
所以是GROUP_CONCAT(CONCAT(student.sname,":",score.score))。

2-3-8. 別名應用

表別名,在表處用as後加上替代的別名符號,列別名是指在列名後帶上as加上替代的別名符號,表別名是全域性呼叫的,列別名可以被having 和 order by 呼叫,如下事例
查詢所有老師所教學生不及格的資訊
表別名:

mysql> SELECT t.tname,GROUP_CONCAT(CONCAT(st.sname,":",s.score)) FROM teacher as t
    -> JOIN course as c ON t.tno=c.tno
    -> JOIN score as s ON c.cno=s.cno
    -> JOIN student as st ON s.sno=st.sno
    -> WHERE s.score <60
    -> GROUP BY t.tno;
+--------+--------------------------------------------+
| tname  | GROUP_CONCAT(CONCAT(st.sname,":",s.score)) |
+--------+--------------------------------------------+
| hesw   | zhang3:59                                  |
| oldguo | li4:40,zh4:40                              |
+--------+--------------------------------------------+

列別名:

mysql> SELECT t.tname as '教師名',GROUP_CONCAT(CONCAT(st.sname,":",s.score)) as '不及格的同學' FROM teacher as t
    -> JOIN course as c ON t.tno=c.tno
    -> JOIN score as s ON c.cno=s.cno
    -> JOIN student as st ON s.sno=st.sno
    -> WHERE s.score <60
    -> GROUP BY t.tno;
+-----------+--------------------+
| 教師名    | 不及格的同學       |
+-----------+--------------------+
| hesw      | zhang3:59          |
| oldguo    | li4:40,zh4:40      |
+-----------+--------------------+