SQL语句之DQL语言(二)(多表查询)

说明:DQL(Data Query Language,数据查询语言),用来查询数据库表中的记录。有的书中,会把DQL语言放入到DML(Data Manipulation Language,数据操作语言:数据的增删改)中,不单独拎出来。但既然有拎出来的,也侧面说明了查询语言的丰富。

查询分为:基本查询、条件查询、分组查询、排序查询、分页查询和多表查询,本文介绍多表查询,前五个的介绍参考:http://t.csdn.cn/VUQCS

SQL语句的书写,要按照上述的顺序,不需要的可以跳过,但不能颠倒顺序;
SQL语句之DQL语言(二)(多表查询)_第1张图片

准备工作:创建表,添加数据

-- 部门管理
create table tb_dept(
                        id int unsigned primary key auto_increment comment '主键ID',
                        name varchar(10) not null unique comment '部门名称',
                        create_time datetime not null comment '创建时间',
                        update_time datetime not null comment '修改时间'
) comment '部门表';

insert into tb_dept
    (id, name, create_time, update_time) values
        (1,'学工部',now(),now()),
        (2,'教研部',now(),now()),
        (3,'咨询部',now(),now()),
        (4,'就业部',now(),now()),
        (5,'人事部',now(),now());

-- 员工管理
create table tb_emp (
                        id int unsigned primary key auto_increment comment 'ID',
                        username varchar(20) not null unique comment '用户名',
                        password varchar(32) default '123456' comment '密码',
                        name varchar(10) not null comment '姓名',
                        gender tinyint unsigned not null comment '性别, 说明: 1 男, 2 女',
                        image varchar(300) comment '图像',
                        job tinyint unsigned comment '职位, 说明: 1 班主任,2 讲师, 3 学工主管, 4 教研主管, 5 咨询师',
                        entrydate date comment '入职时间',
                        dept_id int unsigned comment '部门ID',
                        create_time datetime not null comment '创建时间',
                        update_time datetime not null comment '修改时间'
) comment '员工表';

insert into tb_emp
    (id, username, password, name, gender, image, job, entrydate,dept_id, create_time, update_time) values
        ('1','sanmao','sm1234','三毛','2','sanmao.jpg','4','2000-01-01','2',now(),now()),
        ('2','dufu','df1234','杜甫','1','dufu.jpg','2','2015-01-01','2',now(),now()),
        ('3','libai','lb1234','李白','1','libai.jpg','2','2008-05-01','2',now(),now()),
        ('4','luxun','lx1234','鲁迅','1','luxun.jpg','2','2007-01-01','2',now(),now()),
        ('5','tuo','tuo123','陀翁','1','tuoweng.jpg','2','2012-12-05','2',now(),now()),
        ('6','maerkesi','ma1234','马尔克斯','1','ma.jpg','3','2013-09-05','1',now(),now()),
        ('7','sate','sa1234','萨特','1','sa.jpg','1','2005-08-01','1',now(),now()),
        ('8','jiamiu','jia123','加缪','1','jia.jpg','1','2014-11-09','1',now(),now()),
        ('9','liqingzhao','li1234','李清照','2','li.jpg','1','2011-03-11','1',now(),now()),
        ('10','tangbohu','tang12','唐伯虎','1','tang.jpg','1','2013-09-05','1',now(),now()),
        ('11','huang','huang123','黄蓉','1','huang.jpg','5','2007-02-01','3',now(),now()),
        ('12','guojing','123456','郭靖','1','guo.jpg','5','2008-08-18','3',now(),now()),
        ('13','zhangfei','123456','张飞','1','zhang.jpg','5','2012-11-01','3',now(),now()),
        ('14','guanyu','123456','关羽','1','guan.jpg','2','2002-08-01','2',now(),now()),
        ('15','zhaoyun','123456','赵云','1','zhao.jpg','2','2011-05-01','2',now(),now()),
        ('16','liubei','123456','刘备','1','liu.jpg','2','2007-01-01','2',now(),now()),
        ('17','sunshangxiang','123456','孙尚香','2','sun.jpg',NULL,'2015-03-21',NULL,now(),now());

直接查询多表,查询的结果是两表记录的组合,叫做笛卡尔积

select * from tb_dept, tb_emp;

SQL语句之DQL语言(二)(多表查询)_第2张图片

这样的结果显然是没有意义的,查询出来的数据,并不是实际的结果,而是表明了两张表记录组合产生的可能结果,多表查询就是在这些结果中,寻找出自己真正需要的记录。

一、连接查询

连接查询,是用多表之间具有联系的字段,查询出想要的结果,分为内连接和外连接。在上面建立的员工表中的dept_id字段,关联了部门表中的主键,即,tb_emp.dept_id=tb_dept.id。

(1)内连接:字段值的交集

隐式内连接:查询员工的姓名,及所属的部门名称;

select tb_emp.name, tb_dept.name from tb_emp, tb_dept

where tb_emp.dept_id=tb_dept.id;

可给表设置别名,简化SQL语句

select e.name, d.name from tb_emp e, tb_dept d

where e.dept_id=d.id;

SQL语句之DQL语言(二)(多表查询)_第3张图片

显示内连接(inner可以省略):查询员工的姓名,及所属的部门名称;

select e.name, d.name from tb_emp e

inner join tb_dept d on e.dept_id = d.id

where e.name='张飞';

inner可以省略

select e.name, d.name from tb_emp e

join tb_dept d on e.dept_id = d.id

where e.name='张飞';

SQL语句之DQL语言(二)(多表查询)_第4张图片

(2)外连接:查询的不仅有交集的数据,还包含左/右表中剩下没有交集的数据,如果没有对应上的,用null来代替;

左外连接:查询员工表所有员工的姓名,和对应的部门名称;

select e.name, d.name from tb_emp e

    left join tb_dept d on e.dept_id = d.id;

SQL语句之DQL语言(二)(多表查询)_第5张图片

右外连接:查询部门所有部门的名称,和对应的员工名称;

select e.name, d.name from tb_emp e

    right join tb_dept d on e.dept_id = d.id;

SQL语句之DQL语言(二)(多表查询)_第6张图片SQL语句之DQL语言(二)(多表查询)_第7张图片

小结

隐式内连接、显示内连接,只是在SQL语句的书写上有区别,会一种就行;

左外连接、右外连接通过更换查询表的顺序,可以做到互换,如左外连接,想达到右外连接的结果,把表的位置互换就行。

二、子查询

根据子查询返回的结果,可分为标量子查询、列子查询、行子查询和表子查询,SQL语句的特点是“嵌套”,可以称之为“嵌套查询”,子查询是指嵌套在查询语句内的select语句,可以理解为完成本次查询需要的条件

SQL语句之DQL语言(二)(多表查询)_第8张图片

(1)标量子查询:查询 “教研部”的所有员工信息;

select * from tb_emp where dept_id=
	
	# 子查询结果为单个值
    (select id from tb_dept where name='教研部');

SQL语句之DQL语言(二)(多表查询)_第9张图片

(2)列子查询:查询“教研部”和“学工部”的所有员工信息;

select * from tb_emp where dept_id in

	# 子查询结果为一列
    (select id from tb_dept where name in ('学工部', '教研部'));

SQL语句之DQL语言(二)(多表查询)_第10张图片

(3)行子查询:查询与“鲁迅”的入职日期及职位都相同的员工信息;

select * from tb_emp where (entrydate, job) = 

	# 子查询结果为单行
	(select entrydate, job from tb_emp where name='鲁迅');

在这里插入图片描述

(4)表子查询:子查询返回的结果为多行多列(表)

select t.name, t.entrydate, d.name 

	# 子查询结果为表
    from (select * from tb_emp where entrydate>'2006-01-01') t, tb_dept d 

        where t.dept_id=d.id;

SQL语句之DQL语言(二)(多表查询)_第11张图片

你可能感兴趣的:(sql,数学建模,数据库)