MySQL初学笔记10.13
连接查询
含义:又称多表查询,当查询字段来自于多个表时,就会用到链接查询
笛卡尔乘积现象:表1有m行,表2有n行,结果m*n行
发生原因:没有有效的链接条件
如何避免:添加有效的连接条件
分类:
按年代分类:
sql92标准:仅仅支持内连接
sql99标准:支持内连接+外连接(左外和右外)+交叉连接
按功能分类:
内连接:
等值连接
非等值连接
自连接
外连接:
左外连接
右外连接
全外连接
交叉连接
一、sql92标准
①等值连接
①多表等值连接的结果为多表的交集部分
②n表连接至少需要n-1个连接条件
③多表的顺序没有要求
④一般需要为表起别名
⑤可以搭配前面介绍的所有子句,比如排序、分组、筛选
案例1:查询女神名和对应的男神名
select name,boyName
from boys,beauty
where beauty.boyfriend_id = boys.id
查询员工名和对应的部门名
select last_name,department_name
from employees,departments
where employees.department_id = departments.department_id
2.为表起别名
提高语言简洁度
区分多个重名字段
注意:如果为表齐了别名,则查询的资源就不能使用原来的表名去限定
案例:查询员工名、工种号、工种名
select last_name,e.job_id,job_title
from employees as e,jobs
where e.job_id = jobs.job_id
3.两个表的顺序是否可以调换
案例:查询员工名、工种号、工种名
·
4.可以加筛选么?
案例1:查询有奖金的员工名、部门名
select e.last_name,d.department_name
from employees e,departments d
where e.department_id = d.department_id
and commission_pct is not null
案例2:查询城市名中第二个字符为o的部门名和城市名
select d.department_name,l.city
from departments d,locations l
where d.location_id = l.location_id
and l.city like '_o%';
5.可以加分组么?
案例1:查询每个城市的部门个数
select count(*) 个数,city
from locations l,departments d
where d.location_id = l.location_id
group by city
案例2:查询有奖金的每个部门的部门名和部门的领导编号和该部门的最低工资
select department_name,d.manager_id,min(salary)
from departments d,employees e
where d.department_id = e.department_id
and commission_pct is not null
group by department_name,d.manager_id
6.可以加排序么?
案例:查询每个工种的工种名和员工的个数,并且按员工个数降序
select job_title,count(*)
from employees e,jobs j
where e.job_id = j.job_id
group by job_title
order by count(*) desc
7.可以实现三表连接?
案例:查询员工名、部门名、所在城市
select last_name,department_name,city
from employees,departments,locations
where employees.department_id = departments.department_id
and departments.location_id = locations.location_id
②等值连接
create table job_grades
(grade_level VARCHAR(3),
lowest_sal INT,
highest_sal INT);
INSERT INTO job_grades
VALUES('A',1000,2999);
INSERT INTO job_grades
VALUES('B',3000,5999);
INSERT INTO job_grades
VALUES('C',6000,9999);
INSERT INTO job_grades
VALUES('D',10000,14999);
INSERT INTO job_grades
VALUES('E',15000,24999);
INSERT INTO job_grades
VALUES('F',25000,40000);
案例1:查询员工的工资和工资级别
select * from job_grades
select salary,grade_level
from employees e ,job_grades g
where salary between g.lowest_sal and g.highest_sal
③自连接
案例:查询员工名和上级的名称
select e.employee_id,e.last_name,m.employee_id,m.last_name
from employees e,employees m
where e.manager_id = m.employee_id;
测试题:
1.显示员工表的最大工资,工资平均值
select max(salary),avg(salary) from employees
2.查询员工表的employee_id,job_id,last_name,按department_id降序,salary升序
select employee_id,job_id,last_name
from employees
order by department_id desc,salary asc
3.查询员工表的job_id中包含a和e的,并且a在e的前面
select job_id
from employees
where job_id like '%a%e%'
4.显示当前日期,以及去前后空格,截取子字符串的函数
select now()
select trim(字符,from '')
select substr(str,startIndex)
select substr(str,startIndex,length)
测试
1.显示所有员工的姓名,部门号和部门名称
select last_name,d.department_id,department_name
from employees e,departments d
where e.department_id = d.department_id
2.查询90号部门员工的job_id和90号部门的location_id
select job_id,location_id
from employees e ,departments d
where d.department_id = e.department_id
and e.department_id = 90
3.查询有奖金的员工的姓名、部门名、location_id、city
select last_name,department_name,l.location_id,city
from employees e,departments d,locations l
where e.department_id = d.department_id
and d.location_id = l.location_id
and e.commission_pct is not null
4.查询city在Toronto工作的员工的last_name,job_id,department_id,department_name
select last_name,job_id,d.department_id,department_name
from employees e ,departments d,locations l
where e.department_id = d.department_id
and d.location_id = l.location_id
and city = 'Toronto'
5.查询每个工种、每个部门的部门名、工种名、最低工资
select department_name,job_title,min(salary)
from employees e ,departments d,jobs j
where e.department_id = d.department_id
and e.job_id = j.job_id
group by department_name,job_title;
6.查询每个国家下的部门个数大于2的国家编号
select country_id ,count(*)
from departments d,locations l
where d.location_id = l.location_id
group by country_id
having count(*)>2