1. 程式人生 > >MySQL之連線查詢,多表查詢(適合練習和初學)

MySQL之連線查詢,多表查詢(適合練習和初學)

Join連線圖

針對以上的多表查詢,我們嘗試做以下的實驗:

Join實驗:

CREATE TABLE `t_dept` (
 `id` INT(11) NOT NULL AUTO_INCREMENT,
 `deptName` VARCHAR(30) DEFAULT NULL,
 `address` VARCHAR(40) DEFAULT NULL,
 PRIMARY KEY (`id`)
) ENGINE=INNODB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;
 
CREATE TABLE `t_emp` (
 `id` INT(11) NOT NULL AUTO_INCREMENT,
 `name` VARCHAR(20) DEFAULT NULL,
  `age` INT(3) DEFAULT NULL,
 `deptId` INT(11) DEFAULT NULL,
empno int  not null,
 PRIMARY KEY (`id`),
 KEY `idx_dept_id` (`deptId`)
 #CONSTRAINT `fk_dept_id` FOREIGN KEY (`deptId`) REFERENCES `t_dept` (`id`)
) ENGINE=INNODB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;
 
 
 
INSERT INTO t_dept(deptName,address) VALUES('華山','華山');
INSERT INTO t_dept(deptName,address) VALUES('丐幫','洛陽');
INSERT INTO t_dept(deptName,address) VALUES('峨眉','峨眉山');
INSERT INTO t_dept(deptName,address) VALUES('武當','武當山');
INSERT INTO t_dept(deptName,address) VALUES('明教','光明頂');
 INSERT INTO t_dept(deptName,address) VALUES('少林','少林寺');
 
INSERT INTO t_emp(NAME,age,deptId,empno) VALUES('風清揚',90,1,100001);
INSERT INTO t_emp(NAME,age,deptId,empno) VALUES('嶽不群',50,1,100002);
INSERT INTO t_emp(NAME,age,deptId,empno) VALUES('令狐沖',24,1,100003);
 
 INSERT INTO t_emp(NAME,age,deptId,empno) VALUES('洪七公',70,2,100004);
INSERT INTO t_emp(NAME,age,deptId,empno) VALUES('喬峰',35,2,100005);
 
INSERT INTO t_emp(NAME,age,deptId,empno) VALUES('滅絕師太',70,3,100006);
INSERT INTO t_emp(NAME,age,deptId,empno) VALUES('周芷若',20,3,100007);
 
 
 
INSERT INTO t_emp(NAME,age,deptId,empno) VALUES('張三丰',100,4,100008);
 
INSERT INTO t_emp(NAME,age,deptId,empno) VALUES('張無忌',25,5,100009);
 
INSERT INTO t_emp(NAME,age,deptId,empno) VALUES('韋小寶',18,null,100010);



ALTER TABLE `t_dept` 
add  CEO  INT(11)  ;
 # CEO=2 值,都應該是t_emp 中id的值。
update t_dept set CEO=2 where id=1;
update t_dept set CEO=4 where id=2;
update t_dept set CEO=6 where id=3;
update t_dept set CEO=8 where id=4;
update t_dept set CEO=9 where id=5;
 

下面來看幾個問題:

1   所有有門派的人員資訊 

mysql> select * from t_dept d left join t_emp e on d.id = e.deptId;
+----+----------+-----------+------+------+--------------+------+--------+--------+
| id | deptName | address   | CEO  | id   | name         | age  | deptId | empno  |
+----+----------+-----------+------+------+--------------+------+--------+--------+
|  1 | 華山     | 華山      |    2 |    1 | 風清揚       |   90 |      1 | 100001 |
|  1 | 華山     | 華山      |    2 |    2 | 嶽不群       |   50 |      1 | 100002 |
|  1 | 華山     | 華山      |    2 |    3 | 令狐沖       |   24 |      1 | 100003 |
|  2 | 丐幫     | 洛陽      |    4 |    4 | 洪七公       |   70 |      2 | 100004 |
|  2 | 丐幫     | 洛陽      |    4 |    5 | 喬峰         |   35 |      2 | 100005 |
|  3 | 峨眉     | 峨眉山    |    6 |    6 | 滅絕師太     |   70 |      3 | 100006 |
|  3 | 峨眉     | 峨眉山    |    6 |    7 | 周芷若       |   20 |      3 | 100007 |
|  4 | 武當     | 武當山    |    8 |    8 | 張三丰       |  100 |      4 | 100008 |
|  5 | 明教     | 光明頂    |    9 |    9 | 張無忌       |   25 |      5 | 100009 |
|  6 | 少林     | 少林寺    | NULL | NULL | NULL         | NULL |   NULL |   NULL |
+----+----------+-----------+------+------+--------------+------+--------+--------+
10 rows in set (0.04 sec)

2   列出所有使用者,並顯示其機構資訊 

mysql> select * from t_emp e left join t_dept d on d.id = e.deptId;
+----+--------------+------+--------+--------+------+----------+-----------+------+
| id | name         | age  | deptId | empno  | id   | deptName | address   | CEO  |
+----+--------------+------+--------+--------+------+----------+-----------+------+
|  1 | 風清揚       |   90 |      1 | 100001 |    1 | 華山     | 華山      |    2 |
|  2 | 嶽不群       |   50 |      1 | 100002 |    1 | 華山     | 華山      |    2 |
|  3 | 令狐沖       |   24 |      1 | 100003 |    1 | 華山     | 華山      |    2 |
|  4 | 洪七公       |   70 |      2 | 100004 |    2 | 丐幫     | 洛陽      |    4 |
|  5 | 喬峰         |   35 |      2 | 100005 |    2 | 丐幫     | 洛陽      |    4 |
|  6 | 滅絕師太     |   70 |      3 | 100006 |    3 | 峨眉     | 峨眉山    |    6 |
|  7 | 周芷若       |   20 |      3 | 100007 |    3 | 峨眉     | 峨眉山    |    6 |
|  8 | 張三丰       |  100 |      4 | 100008 |    4 | 武當     | 武當山    |    8 |
|  9 | 張無忌       |   25 |      5 | 100009 |    5 | 明教     | 光明頂    |    9 |
| 10 | 韋小寶       |   18 |   NULL | 100010 | NULL | NULL     | NULL      | NULL |
+----+--------------+------+--------+--------+------+----------+-----------+------+
10 rows in set (0.00 sec)

3   列出不入派的人員:

mysql> select * from t_emp where deptId is null;
+----+-----------+------+--------+--------+
| id | name      | age  | deptId | empno  |
+----+-----------+------+--------+--------+
| 10 | 韋小寶    |   18 |   NULL | 100010 |
+----+-----------+------+--------+--------+
1 row in set (0.01 sec)


mysql> select * from t_emp e left join t_dept d on e.deptId = d.id where e.deptId is null;
+----+-----------+------+--------+--------+------+----------+---------+------+
| id | name      | age  | deptId | empno  | id   | deptName | address | CEO  |
+----+-----------+------+--------+--------+------+----------+---------+------+
| 10 | 韋小寶    |   18 |   NULL | 100010 | NULL | NULL     | NULL    | NULL |
+----+-----------+------+--------+--------+------+----------+---------+------+
1 row in set (0.00 sec)

4  所有沒人入的門派 :

mysql> select * from t_dept d left join t_emp e on d.id = e.deptId where e.id is null;
+----+----------+-----------+------+------+------+------+--------+-------+
| id | deptName | address   | CEO  | id   | name | age  | deptId | empno |
+----+----------+-----------+------+------+------+------+--------+-------+
|  6 | 少林     | 少林寺    | NULL | NULL | NULL | NULL |   NULL |  NULL |
+----+----------+-----------+------+------+------+------+--------+-------+
1 row in set (0.00 sec)

 5 列出所有人員和門派的對照關係

mysql> select * from t_emp e left join t_dept d on e.deptId = d.id
    -> union 
    -> select * from t_emp e right join t_dept d on e.deptId = d.id;
+------+--------------+------+--------+--------+------+----------+-----------+------+
| id   | name         | age  | deptId | empno  | id   | deptName | address   | CEO  |
+------+--------------+------+--------+--------+------+----------+-----------+------+
|    1 | 風清揚       |   90 |      1 | 100001 |    1 | 華山     | 華山      |    2 |
|    2 | 嶽不群       |   50 |      1 | 100002 |    1 | 華山     | 華山      |    2 |
|    3 | 令狐沖       |   24 |      1 | 100003 |    1 | 華山     | 華山      |    2 |
|    4 | 洪七公       |   70 |      2 | 100004 |    2 | 丐幫     | 洛陽      |    4 |
|    5 | 喬峰         |   35 |      2 | 100005 |    2 | 丐幫     | 洛陽      |    4 |
|    6 | 滅絕師太     |   70 |      3 | 100006 |    3 | 峨眉     | 峨眉山    |    6 |
|    7 | 周芷若       |   20 |      3 | 100007 |    3 | 峨眉     | 峨眉山    |    6 |
|    8 | 張三丰       |  100 |      4 | 100008 |    4 | 武當     | 武當山    |    8 |
|    9 | 張無忌       |   25 |      5 | 100009 |    5 | 明教     | 光明頂    |    9 |
|   10 | 韋小寶       |   18 |   NULL | 100010 | NULL | NULL     | NULL      | NULL |
| NULL | NULL         | NULL |   NULL |   NULL |    6 | 少林     | 少林寺    | NULL |
+------+--------------+------+--------+--------+------+----------+-----------+------+
11 rows in set (0.00 sec)

注意:union可以去掉重複的資料

6 列出所有沒入派的人員和沒人入的門派

mysql> select * from t_emp e left join t_dept d on e.deptId = d.id where e.deptId is null
    -> union
    -> select * from t_emp e right join t_dept d on e.deptId = d.id where e.id is null;
+------+-----------+------+--------+--------+------+----------+-----------+------+
| id   | name      | age  | deptId | empno  | id   | deptName | address   | CEO  |
+------+-----------+------+--------+--------+------+----------+-----------+------+
|   10 | 韋小寶    |   18 |   NULL | 100010 | NULL | NULL     | NULL      | NULL |
| NULL | NULL      | NULL |   NULL |   NULL |    6 | 少林     | 少林寺    | NULL |
+------+-----------+------+--------+--------+------+----------+-----------+------+
2 rows in set (0.00 sec)

7,求各個門派對應的掌門人名稱:

mysql> select * from t_dept d left join t_emp e on d.ceo = e.id;
+----+----------+-----------+------+------+--------------+------+--------+--------+
| id | deptName | address   | CEO  | id   | name         | age  | deptId | empno  |
+----+----------+-----------+------+------+--------------+------+--------+--------+
|  1 | 華山     | 華山      |    2 |    2 | 嶽不群       |   50 |      1 | 100002 |
|  2 | 丐幫     | 洛陽      |    4 |    4 | 洪七公       |   70 |      2 | 100004 |
|  3 | 峨眉     | 峨眉山    |    6 |    6 | 滅絕師太     |   70 |      3 | 100006 |
|  4 | 武當     | 武當山    |    8 |    8 | 張三丰       |  100 |      4 | 100008 |
|  5 | 明教     | 光明頂    |    9 |    9 | 張無忌       |   25 |      5 | 100009 |
|  6 | 少林     | 少林寺    | NULL | NULL | NULL         | NULL |   NULL |   NULL |
+----+----------+-----------+------+------+--------------+------+--------+--------+
6 rows in set (0.00 sec)

mysql> select * from t_dept d inner join t_emp e on d.ceo = e.id;
+----+----------+-----------+------+----+--------------+------+--------+--------+
| id | deptName | address   | CEO  | id | name         | age  | deptId | empno  |
+----+----------+-----------+------+----+--------------+------+--------+--------+
|  1 | 華山     | 華山      |    2 |  2 | 嶽不群       |   50 |      1 | 100002 |
|  2 | 丐幫     | 洛陽      |    4 |  4 | 洪七公       |   70 |      2 | 100004 |
|  3 | 峨眉     | 峨眉山    |    6 |  6 | 滅絕師太     |   70 |      3 | 100006 |
|  4 | 武當     | 武當山    |    8 |  8 | 張三丰       |  100 |      4 | 100008 |
|  5 | 明教     | 光明頂    |    9 |  9 | 張無忌       |   25 |      5 | 100009 |
+----+----------+-----------+------+----+--------------+------+--------+--------+
5 rows in set (0.01 sec)

8,求所有當上掌門人的平均年齡:

mysql> select avg(age) from t_dept d inner join t_emp e on d.ceo = e.id;
+----------+
| avg(age) |
+----------+
|  63.0000 |
+----------+
1 row in set (0.01 sec)

mysql> select avg(age) from t_dept d inner join t_emp e on d.ceo = e.id;
+----------+
| avg(age) |
+----------+
|  63.0000 |
+----------+
1 row in set (0.00 sec)

聚合函式能夠自動去重。

  9,求所有人物對應的掌門名稱:

mysql> select e1.id,e1.name,d.deptName,d.address,e2.name as DeptName from t_emp e1 left join t_dept d on e1.deptId = d.id left join t_emp e2 on d.ceo = e2.id;
+----+--------------+----------+-----------+--------------+
| id | name         | deptName | address   | DeptName     |
+----+--------------+----------+-----------+--------------+
|  1 | 風清揚       | 華山     | 華山      | 嶽不群       |
|  2 | 嶽不群       | 華山     | 華山      | 嶽不群       |
|  3 | 令狐沖       | 華山     | 華山      | 嶽不群       |
|  4 | 洪七公       | 丐幫     | 洛陽      | 洪七公       |
|  5 | 喬峰         | 丐幫     | 洛陽      | 洪七公       |
|  6 | 滅絕師太     | 峨眉     | 峨眉山    | 滅絕師太     |
|  7 | 周芷若       | 峨眉     | 峨眉山    | 滅絕師太     |
|  8 | 張三丰       | 武當     | 武當山    | 張三丰       |
|  9 | 張無忌       | 明教     | 光明頂    | 張無忌       |
| 10 | 韋小寶       | NULL     | NULL      | NULL         |
+----+--------------+----------+-----------+--------------+
10 rows in set (0.00 sec)