MySQL学习笔记八:多表查询

创建两张表:dept表和emp表 

/*创建部门表*/
CREATE TABLE dept(
	deptno		INT 	PRIMARY KEY,
	dname		VARCHAR(50),
	loc 		VARCHAR(50)
);

/*创建雇员表*/
CREATE TABLE emp(
	empno		INT 	PRIMARY KEY,
	ename		VARCHAR(50),
	job		VARCHAR(50),
	mgr		INT,
	hiredate	DATE,
	sal		DECIMAL(7,2),
	COMM 		DECIMAL(7,2),
	deptno		INT,
	CONSTRAINT fk_emp FOREIGN KEY(mgr) REFERENCES emp(empno)
);
/*插入dept表数据*/
INSERT INTO dept VALUES (10, '教研部', '北京');
INSERT INTO dept VALUES (20, '学工部', '上海');
INSERT INTO dept VALUES (30, '销售部', '广州');
INSERT INTO dept VALUES (40, '财务部', '武汉');

/*插入emp表数据*/
INSERT INTO emp VALUES (1009, '曾阿牛', '董事长', NULL, '2001-11-17', 50000, NULL, 10);
INSERT INTO emp VALUES (1004, '刘备', '经理', 1009, '2001-04-02', 29750, NULL, 20);
INSERT INTO emp VALUES (1006, '关羽', '经理', 1009, '2001-05-01', 28500, NULL, 30);
INSERT INTO emp VALUES (1007, '张飞', '经理', 1009, '2001-09-01', 24500, NULL, 10);
INSERT INTO emp VALUES (1008, '诸葛亮', '分析师', 1004, '2007-04-19', 30000, NULL, 20);
INSERT INTO emp VALUES (1013, '庞统', '分析师', 1004, '2001-12-03', 30000, NULL, 20);
INSERT INTO emp VALUES (1002, '黛绮丝', '销售员', 1006, '2001-02-20', 16000, 3000, 30);
INSERT INTO emp VALUES (1003, '殷天正', '销售员', 1006, '2001-02-22', 12500, 5000, 30);
INSERT INTO emp VALUES (1005, '谢逊', '销售员', 1006, '2001-09-28', 12500, 14000, 30);
INSERT INTO emp VALUES (1010, '韦一笑', '销售员', 1006, '2001-09-08', 15000, 0, 30);
INSERT INTO emp VALUES (1012, '程普', '文员', 1006, '2001-12-03', 9500, NULL, 30);
INSERT INTO emp VALUES (1014, '黄盖', '文员', 1007, '2002-01-23', 13000, NULL, 10);
INSERT INTO emp VALUES (1011, '周泰', '文员', 1008, '2007-05-23', 11000, NULL, 20);
INSERT INTO emp VALUES (1001, '甘宁', '文员', 1013, '2000-12-17', 8000, NULL, 20);

 1.多表查询的分类

  • 合并结果集
  • 连接查询
  • 子查询

2.合并结果集

2.1 作用:合并结果集就是把两个select语句的查询结果合并到一起!要求被合并的表中,列的类型和列数相同!

2.2 合并结果集有两种方式:

  • UNION:去除重复记录,例如:SELECT * FROM t1 UNION SELECT * FROM t2;
  • UNION ALL:不去除重复记录,例如:SELECT * FROM t1 UNION ALL SELECT * FROM t2
/*创建t1表*/
create table t1(
name varchar(20),
age int
);

/*添加数据*/
insert into t1
values
('张三',20),
('李四',25),
('王五',22);
/*创建t2表*/
create table t2(
name varchar(20),
age int
);

/*添加数据*/
insert into t2
values
('zs',30),
('ls',25),
('张三',20);

3.连接查询

连接查询就是求出多个表的乘积,例如t1连接t2,那么查询出的结果就是t1*t2。

连接查询会产生笛卡尔积,假设集合A={a,b},集合B={0,1,2},则两个集合的笛卡尔积为{(a,0),(a,1),(a,2),(b,0),(b,1),(b,2)}。可以扩展到多个集合的情况。

那么多表查询产生这样的结果并不是我们想要的,那么怎么去除重复的,不想要的记录呢?可以通过使用主外键来去除无用的信息! 

3.1 内连接

  • 方言:SELECT * FROM 表1 别名1, 表2 别名2 WHERE 别名1.xx=别名2.xx
  • 标准:SELECT * FROM 表1 别名1 INNER JOIN 表2 别名2 ON 别名1.xx=别名2.xx
  • 自然:SELECT * FROM 表1 别名1 NATURAL JOIN 表2 别名2

 3.1.1 SQL方言

3.1.2 SQL标准的内连接

 3.1.3  自然连接

3.2 外连接

3.2.1 分类

  • 左外连接
  • 右外连接
  • 全外连接(MySQL不支持)

3.2.2 左外连接

左外连接是先查询出左表(即以左表为主),然后查询右表,右表中满足条件的显示出来,不满足条件的显示NULL。

其中emp表“张三”这条记录中,部门编号为50,而dept表中不存在部门编号为50的记录,所以“张三”这条记录,不能满足e.deptno=d.deptno这个条件。但在左外连接中,因为emp表是左表,所以左表中的记录都会查询出来,即“张三”这条记录也会查出,但相应的右表部分显示NULL !

3.2.3 右外连接

右外连接就是先把右表中所有记录都查询出来,然后左表满足条件的显示,不满足显示NULL。例如在dept表中编号为40的部门并不存在员工,但在右连接中,如果dept表为右表,那么还是会查出40部门,但相应的员工信息为NULL。 

3.3 自然连接(属于一种简化方式)

4.子查询

子查询就是嵌套查询,即SELECT中包含SELECT,如果一条语句中存在两个,或两个以上SELECT,那么就是子查询语句了。

4.1 子查询出现的位置:

  • where后,作为条件的一部分;
  • from后,作为被查询的一条表;

4.2 当子查询出现在where后作为条件时,还可以使用如下关键字:

  • any
  • all

4.3 子查询结果集的形式:

  • 单行单列(用于条件)
  • 单行多列(用于条件)
  • 多行单列(用于条件)
  • 多行多列(用于表)

5.子查询练习题

5.1 工资高于甘宁的员工

  • 子查询作为条件
  • 子查询形式为单行单列

5.2 工资高于30部门所有人的员工信息

第一种方式:

  • 子查询作为条件
  • 子查询形式为多行单列(当子查询结果集形式为多行单列时可以使用ALL或ANY关键字)

第二种方式:

  • 子查询作为条件
  • 子查询形式为单行单列

5.3 查询工作和工资与殷天正完全相同的员工信息

  • 子查询作为条件
  • 子查询形式为单行多列

5.4 查询员工编号为1006的员工名称、员工工资、部门名称、部门地址

5.4.1 第一种方式:

  • 子查询作为表
  • 子查询形式为多行多列

第二种方式:

emp表与dept表做内连接查询:

猜你喜欢

转载自blog.csdn.net/weixin_44679832/article/details/105281515