准备数据库表 t_dept 和 t_emp
CREATE TABLE `t_dept` (
`id` int NOT NULL AUTO_INCREMENT,
`deptName` varchar(30) DEFAULT NULL,
`address` varchar(40) DEFAULT NULL,
`CEO` int DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=7 DEFAULT CHARSET=utf8mb3
CREATE TABLE `t_emp` (
`id` int NOT NULL AUTO_INCREMENT,
`name` varchar(20) DEFAULT NULL,
`age` int DEFAULT NULL,
`deptId` int DEFAULT NULL,
`empno` int NOT NULL,
PRIMARY KEY (`id`),
KEY `idx_dept_id` (`deptId`)
) ENGINE=InnoDB AUTO_INCREMENT=11 DEFAULT CHARSET=utf8mb3
1. 所有有门派的人员信息 ( A、B两表共有)
SELECT * FROM t_emp a INNER JOIN t_dept b ON a.deptId=b.id;
2. 列出所有用户,并显示其机构信息 (A的全集)
SELECT * FROM t_emp a LEFT JOIN t_dept b ON a.deptId=b.id;
3. 列出所有门派(B的全集)
SELECT * FROM t_emp a RIGHT JOIN t_dept b ON a.deptId=b.id;
4. 所有不入门派的人员 (A的独有)
SELECT * FROM t_emp a LEFT JOIN t_dept b ON a.deptId=b.id WHERE a.deptId IS NULL;
5. 所有没人入的门派(B的独有)
SELECT * FROM t_emp a RIGHT JOIN t_dept b ON a.deptId=b.id WHERE a.deptId IS NULL;
6. 列出所有人员和机构的对照关系(AB全有)
MySQL Full Join的实现 因为MySQL不支持FULL JOIN,下面是替代方法
left join + union(可去除重复数据) + right join
union用于把来自多个select 语句的结果组合到一个结果集合中。
当使用union 时,mysql 会把结果集中重复的记录删掉,而使用union all ,mysql 会把所有的记录返回,且效率高于union 。
SELECT * FROM t_emp a LEFT JOIN t_dept b ON a.deptId=b.id
UNION
SELECT * FROM t_emp a RIGHT JOIN t_dept b ON a.deptId=b.id WHERE a.deptId IS NULL;
7. 列出所有没入派的人员和没人入的门派(A的独有+B的独有)
SELECT * FROM t_emp a LEFT JOIN t_dept b ON a.deptId=b.id WHERE a.deptId IS NULL
UNION
SELECT * FROM t_emp a RIGHT JOIN t_dept b ON a.deptId=b.id WHERE a.deptId IS NULL;
8. 求各个门派对应的掌门人名称
select * from t_dept a left join t_emp b on a.CEO=b.id;
9. 求所有当上掌门人的平均年龄
select avg(a.age) from t_emp a inner join t_dept b on a.id=b.CEO;
10. 求所有人物对应的掌门名称
方法一
select c.name,c.id,v.name from t_emp c
LEFT JOIN (select a.deptName,a.id,b.name from t_dept a left join t_emp b on a.ceo=b.id) v on c.deptId=v.id
方法二
select c.name,c.id,v.name from (select a.deptName,a.id,b.name from t_dept a left join t_emp b on a.ceo=b.id) v
LEFT JOIN t_emp c on c.deptId=v.id
方法三
select a.name,a.id,c.name from t_emp a
LEFT JOIN t_dept b on a.deptId=b.id
LEFT JOIN t_emp c on b.ceo=c.id
# No4
select a.name,a.id,(select c.name from t_emp c where c.id=b.ceo) from t_emp a
LEFT JOIN t_dept b on a.deptId=b.id