1.多表查询
笛卡尔积:有两个集合A,B,取这两个集合的所有组成情况
要完成多表查询,需要消除无用的数据
内连接查询
隐式内连接
-- 查询所有员工信息和对应的部门信息
SELECT * FROM emp,dept WHERE emp.'dept_id' = dept.'id';
-- 查询员工表的名称,性别,部门名称
SELECT emp.name,emp.gender,dept.name FROM emp,dept WHERE emp.'dept_id' = dept.'id';
SELECT
t1.name, -- 员工表的姓名
t1.gender, -- 员工表的性别
t2.name -- 部门表的名称
FROM
emp t1,
dept t2
WHERE
t1.'dept_id' = t2.'id';
显式内连接
语法:select 字段列表 from 表名1 inner join 表名2 on 条件
SELECT * FROM emp INNER JOIN dept ON emp.'dept_id' = dept.'id';
SELECT * FROM emp JOIN dept ON emp.'dept_id' = dept.'id';
外连接查询
1.左外连接:
语法:select 字段列表 from 表1 left [outer] join 表2 on 条件;
-- 查询所有员工信息,如果员工有部门,则查询部门名称,没有部门,则不显示部门名称
SELECT
t1.*,t2.'name'
FROM
emp t1,dept t2
WHERE
t1.'dept_id' = t2.'id';
-------
查询的是左表所有的数据以及其交集部分
SELECT
t1.*,t2.'name'
FROM
emp t1 LEFT JOIN dept t2
ON
t1.'dept_id' = t2.'id';
1.右外连接:
2.2.13.1
子查询-
查询中嵌套查询,称嵌套查询为子查询
-- 查询工资最高的员工信息
-- 1.查询最高的工资是多少 9000
SELECT MAX(salary) FROM emp;
-- 2.查询员工信息,并且工资等于9000的
SELECT * FROM emp WHERE emp.'salary' = 9000;
-- 一条sql就完成这个操作
SELECT * FROM emp WHERE emp.'salary' = (SELECT MAX(salary) FROM emp);
1.子查询的结果是单行单列的;--运算符:> >= < <= =
2.子查询的结果是多行单列的;
3.子查询的结果是多行多列的;
-- 查询财务部和市场部所有的员工信息
SELECT id FROM dept WHERE NAME = '财务部' OR NAME = '市场部';
SELECT * FROM emp WHERE dept_id = 3 OR dept = 2;
SELECT * FROM emp WHERE dept_id IN (3,2);
-- 多行单列的 使用运算符 IN
SELECT * FROM emp WHERE dept_id IN (SELECT id FROM dept WHERE NAME = '财务部' OR NAME = '市场部');
-- 多行多列
子查询可以作为一张虚拟表
--查询员工入职日期是2011-11-11日之后的员工信息和部门信息
SELECT * FROM emp WHERE emp.'join_date' > '2011-11-11';
SELECT * FROM dept t1,(SELECT * FROM emp WHERE emp.'join_date' > '2011-11-11') t2 WHERE t1.id = t2.dept_id
-- 用普通的内连接实现
SELECT * FROM emp t1,dept t2 WHERE t1.'dept_id' = t2.'id' AND t1.'join_data' > '2011-11-11';
2.2.14.8
多表查询练习
3.查询员工姓名,工资,工资等级
分析:1.员工姓名,工资emp 工资等级 salarygrade
SELECT
t1.ename,
t1.'salary',
t2.*
FROM emp t1,salarygrade t2
WHERE t1.'salary' BETWEEN t2.'losalary' AND t2.'hisalary';
4.查询员工姓名,工资,职务名称,职务描述,部门名称,部门位置,工资等级
分析:1.分别对应四张表
2.条件 emp.job_id = job.id and emp.dept_id = dept.id and emp.salary BETWEEN
SELECT
t1.'ename',
t1.'salary',
t2.'jname',
t2.'description',
t3.'dname',
t3.'loc',
t4.'grade'
FROM
emp t1,job t2,dept t3,salarygrade t4
WHERE
t1.'job_id' = t2.'id'
AND t1.'dept_id' = t3.'id'
AND t1.'salary' BETWEEN t4.'losalary' AND t4.'hisalary';
5.查询出部门编号,部门名称,部门位置,部门人数
分析:1.dept 表 emp表
2.使用分组查询,按照emp.dept_id完成分组,查询count(id)
3.使用子查询将第二步的查询结果和dept表进行关联查询
SELECT
dept_id,COUNT(id)
FROM
emp
GROUP BY dept_id
-------------
SELECT
t1.'id',t1.'dname',t1.'loc',t2.total
FROM
dept t1,
(SELECT
dept_id,COUNT(id) total
FROM
emp
GROUP BY dept_id) t2
WHERE
t1.'id' = t2.dept_id;
6.查询所有员工的姓名及其直接上级的名称,没有领导的员工也需要查询
分析:1.姓名 emp ,直接上级的姓名 emp
emp表的id和mgr是自关联
2.条件emp.id = emp.mgr
3.查询左表的所有数据,和交集数据-使用左外连接查询
SELECT
t1.ename,
t1.mgr,
t2.'id',
t2.ename
FROM emp t1,emp t2
WHERE t1.mgr = t1.'id'
----------------
SELECT
t1.ename,
t1.mgr,
t2.'id',
t2.'ename'
FROM
emp t1
LEFT JOIN emp t2
ON t1.'mgr' = t2.'id';