一,
1,含义:连接查询又称多表查询,当查询的字段来自于多个表时,就会用到连接查询,2,笛卡尔乘,2
2,现象:表1 有m行,表2 有n行 结果=m*n行,
3,发生的原因:没有有效的连接条件,
4,如何避免:添加有效的连接条件
5,分类:
按年代分类:
sql92标准
sql99标准【推荐】
按功能分类:
内连接:
等值连接
非等值连接
自连接
外连接:
左外连接
右外连接
全外连接
交叉连接
6,小案例
select name,boyname from boys, beauty
where beauty.boyfriend_id=boys.id;
二,sql92标准
1,等值连接:
注:
多表等值连接 的结果为多表的交集部分
n表连接,至少需要n-1个连接条件
多表的顺序没有要求
一般需要为表取别名
可以搭配前面介绍的所有子句使用,比如排序,分组,筛选
案例1:查询女神名和对应的男神名字
select name ,boyname
from boys,beauty
where beauty.boyfriend_id=boy.id;
案例2:查询员工名和对应的部门名
select last_name,department_name
from employees,departments
where employees.depatment_id = departments.depatment_id
2,为表起别名
注意:起别名之后就不能用原来的表名
两个表的顺序可以调换
案例1:查询员工名,工种名,工种号
select last_name,e.job_id,j.job_title
from employees as e,jobs as j
where e.'job_id' = j.'job_id'
案例2:查询有奖金的员工名,部门名
select last_name,department_id,bonus
from employees as e,departments as d
where e.'department_id' = d.'department_id'
and e.'bonus' is not null
案例3:查询城市名中第二个字符为o的命门名和城市名
select department_name,city
from departments as d,location as l
where d.'laoction_id' = l.'location_id'
and city like '_o%'
3,加分组
案例1:查询每个城市的部门个数
select count(*) 个数,city
from departments as d, locations as l
where d.'laoction_id' = l.'location_id'
group by city
案列2:查询有奖金的每个部门的部门名和部门的领导编号和该部门的最低工资
select depatment_name,department_id,d.'manage_id',min(salary)
from employees as e,departments as d
where d.'department_id' = e.'department_id'
and bonus is not null
group by department_name,d.'manage_id';
3,加排序
案例1:查询每个工种的工种名和员工个数,并且按员工个数降序
select job_title ,count(*)
from employees e,jobs j
where e.’job_id' = j.;job_id'
group by job_title
order by count(*) desc;
4,实现三表连接
案例:查询员工名,部门名和所在的城市
select last_name,department_name,city
from employees e,departments s,location l
where e.'department_id' = d.'department_id'
非等值连接:
案例1:查询员工的工资和工资级别
select salary, grade_level
from employees e, job_grades g
where salary between g.'lowest_sal' and g.'height_sal'
自连接:
案例:查询 员工名以及他的上级名称
select last_name, e.employee_id, m.manage_id, m.last_name
from employees e, employees m
where e.'manage_id' = e.'employee_id'
三,SQL99语法
语法:
select 查询列表
from 表1 别名 【连接类型】
join 表2 别名 on
【where 筛选条件】
【order by 分组】
【having 筛选条件】
【order by 排序条件】
分类:
内连接:inner
外连接:
左外:left【outer】
右外:right【outer】
全外:full 【outer]
交叉连接:cross
二,具体事例:
1,等值连接
案例:查询员工名,部门名
select last_name,department_name
from employees e
inner join departments d
on e.'departments_id' = d.'departments_id';
案例2:查询名字中包含e的员工名和工种名(添加筛选条件)
select last_name,job_title
from employees e
inner join jobs j
on e.'job_id' = j.'job_id';
案例3:查询部门个数>3的城市名和部门个数(添加分组+筛选)
select city, count(*) 部门个数
from departments d
inner join locations l
on d.'location_id' = l,'location_id'
having count(*)>3;
案例4:
select count(*) 个数,department_name
from employees e
inner join departments d
on e.'department_id' = d.'department_id'
group by department_name
having count(*)>3
order by ccount(*) desc;
案例5:查询员工名,部门名,工种名,并且按部门名降序(添加三表连接)
select last_name,department_name,job_title
from employees e
inner join deartments d on e.'department_id' = d.'department_id'
inner join jobs j on e.'job_id' = j.'job_id'
order by department_name desc;
2,非等值连接:
案例:查询员工工资级别
select salary ,grade_level
from employees e
join job_grades g
on e.'salary' between g.'lowest_sal' and g.'heightest_sal';
案例:查询工资级别>20的个数,并且按工资级别降序
select count(*) ,grade_level
from employees e
join on job_grades g
on e.'salary' between g.'lowest_sal' and g.'height_sal'
group by grade_level
having count(*)>20
order by grade_level desc;
3,自连接
案例:查询员工的名字有含字母k的,上级的名字
select e.last_name, m.last_name
from employees e
join employees m
on e.'manage_id' = m.'department_id'
where e.'last_name' like '%k%';
二,外连接(一个表中有,另一个表中没有)
特点:
1,外连接查询的结果为主表中的所有记录
如果从表中 有和他匹配的,则显示匹配值
如果从表中没有和他匹配的,则显示null值
外连接查询的结果=内连接结果+主表中有而从表中没有的记录
2,左外连接,left join 左边是主表
右外连接,right join 右边是主表
3,左外和右外交换两个表的顺序,可以实现同样的效果
案例:查询没有女朋友的女神名
左外连接
select b.name
from beautiful b
left outer join boys bo
on b.'boyfriend_id' = bo.'id'
where bo.id is null
右外连接
select b.name
from boys bo
right outer join beautiful b
on b.'boyfriend_id' = bo.'id'
where bo.id is null
全外连接:
mysql不支持
use girls;
select b.*, g.*
from beauty b
full outer join boys bo
on b.'boyfriend_id' = bo.'id'
交叉连接:
select b.*, bo.*
from beauty b
cross join boys bo;