一、笛卡尔积的多表查询
1.案例 查询员工名为’Abel’的员工在哪个城市工作?
2.出现笛卡尔积(交叉连接)的错误
select employee_id, department_name
from employees,departments
为什么出现2889条记录?
Employees 107 Departments 27
每个员工和每个部分都匹配了一遍 107*27=2889
缺少了多表连接的条件
3.多表查询的正确方式,需要有连接条件
①两个表的连接条件
select last_name,department_name
from employees e,departments d
where e.department_id = d.department_id
②两个表的字段名相同(where 条件后面的),需要指明字段的表
select last_name,department_name,e.department_id
from employees e,departments d
where e.department_id = d.department_id
③sql优化:建议多表查询时,每个字段指明其所在的表
select e.last_name,e.department_id,d.department_name
from employees e,departments d
where e.department_id = d.department_id
④可以给表起别名,可以在select和where使用表的别名。起了别名不能使用原名。
⑤n个表实现多表查询,至少n-1个连接条件
4.查询员工的department_id,last_name,department_name,city
select e.employee_id,e.last_name,d.department_name,l.city
from employees e,departments d,locations l
where e.department_id=d.department_id and d.location_id=l.location_id
二、等值连接和非等值连接,自连接和非自连接
1.多表查询的分类
角度1:等值连接 VS 非等值连接
角度2:自连接 VS 非自连接
角度3:内连接 VS 外连接
2.等值连接 VS 非等值连接
①非等值连接的举例:查询员工的工资等级
select last_name,salary,grade_level
from employees e,job_grades j
where salary between j.lowest_sal and j.highest_sal
或
select last_name,salary,grade_level
from employees e,job_grades j
where salary >= lowest_sal and salary<=highest_sal
3. 自连接 VS 非自连接
自连接:1个表。表自己连接自己
非自连接:多个表
①查询员工id,员工姓名和主管姓名
select e1.employee_id,e1.last_name,e2.last_name manager_name
from employees e1,employees e2
where e1.manager_id=e2.employee_id
4.内连接 VS 外连接
左表:员工表employees,有些员工没有部门
右表:部门表departments,有些部门存在,没有左表的员工
①内连接:以上练习都是内连接。交集
107个人,查询106个记录。左表和右表满足查询条件的结果
select employee_id,department_name
from employees e,departments d
where e.department_id=d.department_id
②外连接:并集
左外连接:查询所有的员工的last_name,epartment_name信息(所有的就是外连接)
select employee_id,department_name
from employees e
left join departments d on e.department_id=d.department_id
③右外连接:
select employee_id,department_name
from employees e
right join departments d on e.department_id=d.department_id
三、7种SQL JOINS的实现
左查询:左表
右查询:右表
【练习题】
1.
select e.last_name,e.department_id,d.department_name
from employees e
left join departments d on e.department_id = d.department_id
2.
select e.employee_id,e.job_id,d.location_id
from employees e
join departments d on d.department_id = e.department_id
where e.department_id = 90
3.
select e.last_name,e.commission_pct,d.department_name,d.location_id,l.city
from employees e
join departments d on e.department_id=d.department_id
join locations l on l.location_id=d.location_id
where e.commission_pct is not null
4.
select e.last_name,e.job_id,e.department_id,d.department_name,l.city
from employees e
join departments d on e.department_id=d.department_id
join locations l on l.location_id=d.location_id
where l.city = 'Toronto'
5.
select d.department_name,l.street_address,e.last_name,e.job_id,e.salary
from employees e
join departments d on e.department_id=d.department_id
join locations l on l.location_id=d.location_id
where d.department_name='Executive'
6.
select e1.last_name "employees",e1.employee_id "Emp#",e2.last_name "manager",e2.employee_id "#Mgr"
from employees e1,employees e2
where e1.manager_id = e2.employee_id and e1.last_name='Kochhar'
或
select e1.last_name "employees",e1.employee_id "Emp#",e2.last_name "manager",e2.employee_id "#Mgr"
from employees e1
join employees e2 on e1.manager_id = e2.employee_id
where e1.last_name='Kochhar'
7.
select e.last_name,d.department_name
from employees e
right join departments d on e.department_id = d.department_id
where e.last_name is null
8.
select d.department_name,l.city
from departments d
right join locations l on d.location_id = l.location_id
where department_name is null
9.
select e.employee_id,e.last_name,e.salary,d.department_name
from employees e
join departments d on d.department_id = e.department_id
where d.department_name = 'IT' or d.department_name = 'Sales'
或
select e.employee_id,e.last_name,e.salary,d.department_name
from employees e
join departments d on d.department_id = e.department_id
where d.department_name in ('Sales','IT')