一、表的关联关系
1.举例一对一关联
查询员工"abel"在那个城市工作
要用的三张表
我们在解决上面这个多表查询的问题之前需要了解一些基本原理
2.笛卡尔积sql语句存在的问题 :
笛卡尔积类似于矩阵乘法运算,所以如果不做处理会产生大量冗余 运算
select employee_id,department_name from employees , departments;
为了解决笛卡尔积产生大量冗余的计算,我们需要设计出一个更好的多表连接运算的方法,也就是需要更多的额运算符加入
因此我们有了下面的语句
select last_name , employee_id , department_name , city from employees , departments , locations where employees.LAST_NAME="abel" and employees.DEPARTMENT_ID=departments.DEPARTMENT_ID and locations.LOCATION_ID = departments.LOCATION_ID;
起别名增加可读性
select last_name , employee_id , department_name , city from employees as e , departments as d , locations as l where e.last_name ="abel" and e.department_id = d.department_id and l.location_id = d.location_id;
二、多表查询的分类
我们拿等值和非等值举例
1.等值连接的例子
非等值
job_grades
我们根据salary来判断员工的薪水等级
select last_name , salary ,grade_level from employee e , job_grades j where e.salary between j.lowest_sal and j.lowest_sal and j.highest_sal;
这个就是非等值连接
2.自连接的例子
查询员工id,员工姓名及其管理员的id和姓名
select emp.employee_id , emp.last_name , mgr.employee_id , mgr.last_name from employees emp , employees mgr where emp.manager_id = mgr.employee_id;
3.内连接和外连接的例子
我们前面写的都是内连接
同理外连接的定义
我们主要讲外连接
分类:
左外连接、右外连接和满连接
外连接实例
左外连接
查询所有的员工的last_name,department_name信息
外连接语法分92和99年不同版本的,99可读性比92要好很多
我们用92年版本的语法写
select employee_id,department_name from employees e , departments d where e.department_id = d.department_id(+);
这里为什么会报错呢?
是因为mysql不支持92版本的写入
我们可以用Oracle执行
三、sql99语法
上面其实都算是sql92语法的内容,所以下面就都讲99语法的内容
使用…ON的方式实现多表的查询,这种方式也能解决外连接的问题,且mysql是支持的。
1.sql99语法实现内连接
select last_name , department_name from employees e join departments d on e.`department_id` = d.`department_id` ;
这数据少了一个人,那个部门为null,还没分配部门
我们看内连接没有这个人
SELECT last_name , department_name FROM employees e JOIN departments d ON e.department_id = d.department_id WHERE last_name = "Grant";
可以看到并没有
2.99语法实现左外连接
因为左表的数据更多,所以我们需要左连接去显示出那个部门为null的人
SELECT last_name , department_name FROM employees e LEFT OUTER JOIN departments d ON e.department_id = d.department_id;
sql92语法是这样的
3.99语法实现右外连接
同理我们查一下所有的部门,员工id
SELECT last_name , department_name FROM employees e RIGHT OUTER JOIN departments d ON e.department_id = d.department_id;
4.99语法实现满外连接
SELECT last_name , department_name FROM employees e FULL OUTER JOIN departments d ON e.department_id = d.department_id;
注意虽然full outer join是对的,但是mysql不支持full
Oracle是支持的