mysql之多表查询
1.新建的一个数据库db3
create database db3 charset utf8;
2.为db3数据库创建两张表和数据
(1)创建person表
create table peron ( id int(11) not null auto_increment, name varchar(50) not null, age tinyint(4) default \'0\', sex enum(\'男\',\'女\',\'人妖\') not null default \'人妖\', salary decimal(10, 2) not null DEFAULT \'250.00\', hire_date date not null, dept_id int(11) default null, PRIMARY KEY (id) ) ENGINE=INNODB auto_increment = 13 DEFAULT CHARSET = utf8;
(2)为person表创建数据
# 教学部 insert into peron values(\'1\', \'alex\', \'28\', \'人妖\', \'53000.00\', \'2010-06-21\', \'1\'); insert into peron values(\'2\', \'wupeiqi\', \'23\', \'男\', \'8000.00\', \'2011-02-21\', \'1\'); insert into peron values(\'3\', \'egon\', \'30\', \'男\', \'6500.00\', \'2015-06-21\', \'1\'); insert into peron values(\'4\', \'jingnvshen\', \'28\', \'女\', \'6680.00\', \'2014-06-21\', \'1\'); # 销售部 insert into peron values(\'5\', \'歪歪\', \'20\', \'女\', \'3000.00\', \'2015-02-21\', \'2\'); insert into peron values(\'6\', \'星星\', \'20\', \'女\', \'2000.00\', \'2018-01-30\', \'2\'); insert into peron values(\'7\', \'格格\', \'20\', \'女\', \'2000.00\', \'2018-02-27\', \'2\'); insert into peron values(\'8\', \'周周\', \'20\', \'女\', \'2000.00\', \'2015-06-21\', \'2\'); #市场部 insert into peron values(\'9\', \'月月\', \'21\', \'女\', \'4000.00\', \'2014-07-21\', \'3\'); insert into peron values(\'10\', \'安琪\', \'22\', \'女\', \'4000.00\', \'2015-07-15\', \'3\'); # 人事部 insert into peron values(\'11\', \'周明月\', \'17\', \'女\', \'5000.00\', \'2014-06-21\', \'4\'); # 鼓励部 insert into peron values(\'12\', \'苍老师\', \'33\', \'女\', \'1000000.00\', \'2018-02-21\', null);
(3)创建一个部门表dept。 COMMENT 表示为字段添加注释
create table dept( did int not null COMMENT \'部门id记录\' auto_increment PRIMARY KEY, dname VARCHAR(50) not null COMMENT \'部门名称\' ) ENGINE=INNODB DEFAULT CHARSET utf8;
(4)为dept部门表,创建部门数据
# 添加部门数据 INSERT INTO dept VALUES(\'1\', \'教学部\'); INSERT INTO dept VALUES(\'2\', \'销售部\'); INSERT INTO dept VALUES(\'3\', \'市场部\'); INSERT INTO dept VALUES(\'4\', \'人事部\'); INSERT INTO dept VALUES(\'5\', \'鼓励部\');
(5)此时部门表与人员表为
3.多表联合查询
3.1 笛卡尔乘积(多个表的结果集相乘)。查询人员表和dept部门表,结果却查询出来了60条,重复的记录出现,这个笛卡尔乘积现象。两个表数据的结果集相乘。这是在多表联合查询时不加条件调导致的
select * from person, dept; -- 查询人员表和dept表
3.2 多表联合查询使用where条件限定。将person表的部门id和dept表的id记录相等的记录查询出来。注意:多表查询时,一定要找到多个表的关联字段,并且将这个关联字段作为条件使用
select * from person as p, dept as d where p.dept_id = d.did; -- person表和dept表进行多表联合查询,条件是人员表的部门dept_id必须和部门表的did相同。
4.多表连接查询。
4.1左连接查询(左侧表为基准表,基准表去匹配右侧的表,不管匹配没匹配上,基准表的数据都会显示出来)
这种方式查询会将person表中的dept_id和dept表中的did字段相等的记录都查询出来,同时还会将person表中没匹配上dept表中的记录查询出来。如人员表中小溢这个记录没有dept_id部门字段值,但是有了左连接所以会将person人员表中dept_id字段没匹配上dept部门表中的did字段的记录也查询出来,左连接,左侧表中没匹配上的记录也会查询出来。
select * from person LEFT JOIN dept ON person.dept_id = dept.did; -- left join关键字,连接关键字左连接
4.2右连接查询(右侧表为基准表,基准表去匹配左侧的表,不管匹配没匹配上,基准表的数据都会显示出来)
这种方式查询会将person表中的dept_id和dept表中的did字段相等的记录都查询出来,同时还会将dept表中没匹配上person表中的记录查询出来。如dept部门表did中开车部没有被person人员表中的dept_id部门id匹配上,但是有了右连接所以会将dept部门表中did字段没匹配上的记录也查询出来,没配上就会显示空值,右连接,右侧表中没匹配上的记录也会查询出来。
select * from person RIGHT JOIN dept ON person.dept_id = dept.did; -- right join关键字,左连接关键字
4.3内连接查询(与多表联合查询的效果一样),两表匹配上的才会被查询出来
select * from person INNER JOIN dept ON person.dept_id = dept.did; -- inner为内连接关键字
4.4全连接查询(显示左右表的全部数据)使用union 可以将左右表的数据去重查询出来,union all 不会讲左右表的数据去重
(1)union,全连接查询关键字,并将左右两表数据去重
select * from person LEFT JOIN dept ON person.dept_id = dept.did UNION select * from person RIGHT JOIN dept ON person.dept_id = dept.did;
(2)union all,全连接查询关键字,不会将左右两表的数据去重
-- union all 关键不会将两表重复的数据去重 select * from person LEFT JOIN dept ON person.dept_id = dept.did UNION all select * from person RIGHT JOIN dept ON person.dept_id = dept.did;
5.复杂条件多表查询
5.1要求查询出教学部年龄大于20岁,并且工资小于40000的员工,按工资时间倒序排序
(1)使用子语句的方法查询
select * from person where age > 20 and dept_id = (select did from dept where dname = \'教学部\') and salary < 40000 ORDER BY salary desc;
(2)使用多表联合查询的方法查询
select * from person as p, dept as d where p.dept_id = d.did and d.dname= \'教学部\' and p.age > 20 and p.salary < 40000 ORDER BY p.salary desc;
5.2查询每个部门中最高工资和最低工资是多少,显示部门名称
(1)使用多表连接查询的方法
SELECT MAX(salary), MIN(salary),dname from person LEFT JOIN dept ON person.dept_id = dept.did GROUP BY dept_id;
(2)使用多表联合查询的方法
select MAX(salary), MIN(salary),dname from person as p, dept as d where p.dept_id = d.did GROUP BY p.dept_id;