MySQL之連線查詢,多表查詢(適合練習和初學)
阿新 • • 發佈:2018-12-16
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)