MySQL—— 多表查询

目录

一. 内连接查询
二. 外连接查询
三. 子查询查询

准备工作,创建表并添加测试数据

-- 创建部门表
CREATE TABLE department(
		pk_id INT PRIMARY KEY AUTO_INCREMENT, 
		name VARCHAR(20)
);
-- 创建员工表
CREATE TABLE employee(
    pk_id INT PRIMARY KEY AUTO_INCREMENT,
    name VARCHAR(10),
    gender CHAR(1),
    salary DOUBLE,
    join_date DATE,
    department_id INT,
    FOREIGN KEY (department_id) REFERENCES department(pk_id)
);

-- 插入数据
INSERT INTO department (name) VALUES ('财务部'), ('咨询部'), ('市场部');

INSERT INTO employee(name,gender,salary,join_date,department_id) VALUES('小张', '男', 7200, '1998-02-24', 1);
INSERT INTO employee(name,gender,salary,join_date,department_id) VALUES('小赵', '男', 3600, '2010-12-02', 2);
INSERT INTO employee(name,gender,salary,join_date,department_id) VALUES('老钱', '男', 9000, '1990-08-08', 2);
INSERT INTO employee(name,gender,salary,join_date,department_id) VALUES('老黑', '女', 5200, '1980-10-07', 2);
INSERT INTO employee(name,gender,salary,join_date,department_id) VALUES('小白', '女', 4500, '2000-03-14', 3);
INSERT INTO employee(name,gender,salary) VALUES('老黄','男','9000');

表中数据如下:
MySQL—— 多表查询_第1张图片

  • 笛卡尔积
    • 获取的是两个集合的所有组成情况。
    • 要完成多表查询,需要消除无用的数据。
      使用 SQL 语句来完成如下:
SELECT * FROM department, employee;

查询结果:
MySQL—— 多表查询_第2张图片

可以看到,通过该SQL语句得到的结果数据是有误的。并且得到的数量是 两个表记录行数的乘积。

接下来,我们看看如何实现有效的多表查询。
多表查询的分类

一. 内连接查询

1、隐式内连接:

语法:使用 where条件来消除无用数据

举例说明:

① 查询所有员工信息和对应的部门信息
SQL语句:

SELECT * FROM		
			employee, 
			department 
WHERE 
			employee.department_id = department.pk_id;

MySQL—— 多表查询_第3张图片

② 查询员工表的名称、性别;部门表的名称
SQL语句:

SELECT 
		employee.name, 
		employee.gender, 
		department.name
FROM 
		employee, 
		department 
WHERE 
		employee.department_id = department.pk_id;

查询结果:
MySQL—— 多表查询_第4张图片
③ 使用②的语法时,我们可以给表起别名
SQL语句:

SELECT
		t1.name, 
		t1.gender,
		t2.name
FROM
		employee t1, 
		department t2 -- 起别名
WHERE
		t1.department_id = t2.pk_id;

查询结果
MySQL—— 多表查询_第5张图片
内连接查询:

  1. 从哪些表中查询数据
  2. 条件是什么
  3. 查询哪些字段
2、显式内连接

语法:SELECT 字段列表 FROM 表名1 [INNER] JOIN 表名2 ON 条件;INNER 可以省略不写。

举例说明:

① 查询所有员工信息和对应的部门信息
SQL语句:

SELECT * FROM 
				employee 
JOIN 
				department 
ON 
				employee.department_id = department.pk_id;

查询结果:
MySQL—— 多表查询_第6张图片
② 查询员工表的名称、性别;部门表的名称
SQL语句:

SELECT
		employee.name,
		employee.gender,
		department.name
FROM
		employee
JOIN
		department
ON
		employee.department_id = department.pk_id;

查询结果:
MySQL—— 多表查询_第7张图片

二. 外连接查询

1、左外连接

语法:SELECT 字段列表 FROM 左表 LEFT [OUTER] JOIN 右边 ON 条件;此处OUTER可以省略。
查询范围:查询的是左表所有数据及其交集部分

SQL语句
查询所有员工和对应的部门名称:

SELECT
			employee.*, department.name
FROM  
			employee 
LEFT JOIN 
			department 
ON 
			employee.department_id = department.pk_id;

查询结果:
MySQL—— 多表查询_第8张图片
虽然我们有条件employee.department_id = department.pk_id;,但是,左表中department_id 为 NULL的数据查出来了。因为它位于左表。

2、右外连接

语法:SELECT 字段列表 FROM 左表 RIGHT [OUTER] JOIN 右表 ON 条件;此处OUTER可以省略。
查询范围:查询的是右表所有数据及其交集部分

SQL语句

SELECT
			employee.*, department.name
FROM  
			employee 
RIGHT JOIN 
			department 
ON 
			employee.department_id = department.pk_id;

查询结果:
MySQL—— 多表查询_第9张图片
坐标空的NULL数据未能查出来。

三. 子查询

概念:当一个查询是另一个查询的条件时,称之为子查询。
举例说明:
查询工资最低的员工信息,我们可以使用2个SQL语句来完成:

SELECT 
			MIN(salary) 
FROM 
			employee;	-- 先查询最低工资
SELECT * FROM 
			employee 
WHERE 
			salary = 9000;  -- 查询工资最低的员工的信息

使用子查询:

SELECT * FROM
			employee 
WHERE 
			salary = (SELECT MIN(salary) FROM employee);

查询结果:
MySQL—— 多表查询_第10张图片
下面来说一下,子查询的不同情况:
1.子查询的结果单行单列,子查询可以作为条件使用:可以使用运算符做判断,运算符:> < >= <= =
例如:查询员工工资小于平均工资的人

SELECT * FROM 
				employee 
WHERE 
				salary < (SELECT AVG(salary) FROM employee);

查询结果:
MySQL—— 多表查询_第11张图片

2.子查询的结果多行单列,子查询可以作为条件使用:可以使用运算符 IN 来判断。
例如:查询’财务部’和‘市场部’所有员工信息

SELECT * FROM 
			employee
WHERE 
			department_id 
IN 	
			(SELECT pk_id FROM department WHERE name = '财务部' OR name = '市场部');

或者:

SELECT * FROM 
			employee
WHERE 
			department_id 
IN 	
			(SELECT pk_id FROM department WHERE name IN ('财务部', '市场部'));

查询结果:
MySQL—— 多表查询_第12张图片
3.子查询的结果多行多列,子查询可以作为一张虚拟表
例如:
需求:查询员工的入职日期1998-02-24之后的员工信息和部门信息
先获取入职日期1998-02-24之后的员工信息

-- 日期判断可以直接使用字符串进行比较。
SELECT * FROM employee WHERE employee.join_date > '1998-02-24';

查询结果:
MySQL—— 多表查询_第13张图片
然后,把上述结果作为一个表,获取入职日期1998-02-24之后的员工信息和部门信息:

SELECT * FROM			
			department t1, 
			(SELECT * FROM employee WHERE employee.join_date > '1998-02-24') t2 
WHERE 
			t1.pk_id = t2.department_id;

查询结果:
MySQL—— 多表查询_第14张图片
同样的,使用内连接也可以实现该需求:

SELECT * FROM
			 employee, department 
WHERE 
			employee.department_id = department.pk_id AND employee.join_date > '1998-02-24';

你可能感兴趣的:(MySQL)