一. 内连接查询
二. 外连接查询
三. 子查询查询
-- 创建部门表
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');
SELECT * FROM department, employee;
可以看到,通过该SQL语句得到的结果数据是有误的。并且得到的数量是 两个表记录行数的乘积。
接下来,我们看看如何实现有效的多表查询。
多表查询的分类
语法:使用 where
条件来消除无用数据
举例说明:
① 查询所有员工信息和对应的部门信息
SQL语句:
SELECT * FROM
employee,
department
WHERE
employee.department_id = department.pk_id;
② 查询员工表的名称、性别;部门表的名称
SQL语句:
SELECT
employee.name,
employee.gender,
department.name
FROM
employee,
department
WHERE
employee.department_id = department.pk_id;
查询结果:
③ 使用②的语法时,我们可以给表起别名
SQL语句:
SELECT
t1.name,
t1.gender,
t2.name
FROM
employee t1,
department t2 -- 起别名
WHERE
t1.department_id = t2.pk_id;
语法:SELECT 字段列表 FROM 表名1 [INNER] JOIN 表名2 ON 条件;
INNER 可以省略不写。
举例说明:
① 查询所有员工信息和对应的部门信息
SQL语句:
SELECT * FROM
employee
JOIN
department
ON
employee.department_id = department.pk_id;
查询结果:
② 查询员工表的名称、性别;部门表的名称
SQL语句:
SELECT
employee.name,
employee.gender,
department.name
FROM
employee
JOIN
department
ON
employee.department_id = department.pk_id;
语法:SELECT 字段列表 FROM 左表 LEFT [OUTER] JOIN 右边 ON 条件;
此处OUTER可以省略。
查询范围:查询的是左表所有数据及其交集部分
SQL语句
查询所有员工和对应的部门名称:
SELECT
employee.*, department.name
FROM
employee
LEFT JOIN
department
ON
employee.department_id = department.pk_id;
查询结果:
虽然我们有条件employee.department_id = department.pk_id;
,但是,左表中department_id 为 NULL
的数据查出来了。因为它位于左表。
语法:SELECT 字段列表 FROM 左表 RIGHT [OUTER] JOIN 右表 ON 条件;
此处OUTER可以省略。
查询范围:查询的是右表所有数据及其交集部分
SQL语句
SELECT
employee.*, department.name
FROM
employee
RIGHT JOIN
department
ON
employee.department_id = department.pk_id;
概念:当一个查询是另一个查询的条件时,称之为子查询。
举例说明:
查询工资最低的员工信息,我们可以使用2个SQL语句来完成:
SELECT
MIN(salary)
FROM
employee; -- 先查询最低工资
SELECT * FROM
employee
WHERE
salary = 9000; -- 查询工资最低的员工的信息
使用子查询:
SELECT * FROM
employee
WHERE
salary = (SELECT MIN(salary) FROM employee);
查询结果:
下面来说一下,子查询的不同情况:
1.子查询的结果单行单列,子查询可以作为条件使用:可以使用运算符做判断,运算符:> < >= <= =
例如:查询员工工资小于平均工资的人
SELECT * FROM
employee
WHERE
salary < (SELECT AVG(salary) FROM employee);
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 ('财务部', '市场部'));
查询结果:
3.子查询的结果多行多列,子查询可以作为一张虚拟表
例如:
需求:查询员工的入职日期1998-02-24之后的员工信息和部门信息
先获取入职日期1998-02-24之后的员工信息
-- 日期判断可以直接使用字符串进行比较。
SELECT * FROM employee WHERE employee.join_date > '1998-02-24';
查询结果:
然后,把上述结果作为一个表,获取入职日期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;
SELECT * FROM
employee, department
WHERE
employee.department_id = department.pk_id AND employee.join_date > '1998-02-24';