#连接查询
/*
含义:又称为多表查询,当查询的字段来自于多个表时,就会用到连接查询
笛卡尔乘积现象:表1 有m行,表2有n行,结果为=m*n行
发生原因:没有有效的连接条件
如何避免:添加有效的连接条件
分类:
按年代分类
sq192标准
sq199标准【推荐】
按功能分类:
内连接:
等值连接
非等值连接
自连接
外连接:
左外连接
右外连接
全外连接
交叉连接:
*/
#一、sq192标准
#1、等值连接
/*
①多表的等值连接的结果为多表的交集部分
②n表连接,至少需要n-1连接条件
③多表的顺序没有要求
④一般需要为表起别名
⑤可以搭配前面所有的查询子句使用,比如排序、分组、筛选
*/
#查询女神名和对应的男神名
select name,boyName from boys,beauty where beauty.boyfriend_id=boys.id;
#查询部门名对应的员工名
select department_name,last_name from employees,departments where employees.department_id=departments.department_id;
#2、为表起别名
/*
①提高语句的简洁度
②区分多个重名的字段
*/
#查询员工名、工种号、工种名
select last_name,e.job_id,job_title from employees e,jobs j where e.job_id=j.job_id;
#3、两个表的顺序是否可以调换
#查询员工名、工种号、工种名
select last_name,e.job_id,job_title from jobs j,employees e where e.job_id=j.job_id;
#4、可以加筛选
#查询有奖金的员工名、部门名
select last_name,department_name from employees,departments where employees.department_id=departments.department_id and commission_pct is not null;
#查询城市名第二个字符为o的部门名和城市名
select department_name,city from departments,locations where departments.location_id=locations.location_id and city like '_o%';
#查询每个城市的部门的个数
select count(*),city from locations,departments where locations.location_id=departments.location_id group by city;
#查询有奖金的每个部门的部门名和部门的领导编号和该部门的最低工资
select department_name,departments.manager_id,min(salary) from employees,departments where departments.department_id=employees.department_id and commission_pct is not null group by department_name;
#6、可以加排序
#查询每个工种的工种名和员工的个数,并且按员工个数降序
select job_title,count(*) from employees,jobs where employees.job_id=jobs.job_id group by job_title order by count(*) desc;
#7、可以实现三表连接
#查询员工名、部门名和所在的城市
select last_name,department_name,city from departments,employees,locations where employees.department_id=departments.department_id and departments.location_id=locations.location_id;
#2、非等值连接
/*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);*/
#查询员工的工资和工资级别
select salary,employee_id from employees;
select salary,grade_level from job_grades,employees where
salary BETWEEN job_grades.lowest_sal and job_grades.highest_sal;
#3、自连接
#查询员工名和上级的名称
select s1.last_name 员工名字,s2.last_name 上级名字 from employees s1,employees s2 where s1.manager_id=s2.employee_id;
#二、sql99语法
/*
语法:
select 查询列表
from 表1 别名 【连接类型】
join 表2 别名
on 连接条件
where 筛选条件
分类
内连接:inner
外连接:
左外:left 【outer】
右外:right 【outer】
全外:full 【outer】
交叉连接:CROSS
*/
# 一)内连接
/*
语法:
select 查询列表
from 表1 别名
inner join 表2 别名
on 连接条件
分类:
等值
非等值
自连接
特点:
1、添加排序、分组、筛选
2、inner可以省略
3、筛选条件可以放在where后面,连接条件放在on后面,提高分离性,便于阅读
4、inner join 连接和sql192语法中的等值连接效果是一样的,都是查询多表的交集
*/
#1、等值连接
#查询员工名、部门名
select last_name,department_name from employees e
INNER JOIN departments d on e.department_id=d.department_id;
#查询名字中包含e的员工名和工种名
select last_name,job_title from employees e INNER JOIN jobs j on e.job_id=j.job_id where e.last_name like '%e%';
#查询部门个数大于3的城市名和部门个数(添加分组+筛选)
select city,COUNT(*) 部门个数 from departments d
INNER JOIN locations l on d.location_id=l.location_id group by city having 部门个数>3;
#查询哪个部门的员工个数大于3的部门名和员工个数,并按个数降序(添加排序)
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 count(*) desc;
#查询员工名、部门名、工种名,并按照部门名降序(三表连接)
select last_name,department_name,job_title from employees e INNER JOIN departments d on e.department_id=d.department_id INNER JOIN jobs j on j.job_id=e.job_id order by department_name;
#2、非等值连接
#查询员工的工资级别
select salary,grade_level from employees e join job_grades g on e.salary BETWEEN g.lowest_sal and g.highest_sal;
#查询每个工资级别的个数>20,并且按照工资级别降序
select count(*),grade_level from employees e join job_grades g on e.salary BETWEEN g.lowest_sal and g.highest_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.manager_id=m.employee_id where e.last_name like 'k%%';
#二、外连接
/*
应用场景:
特点:
1、外连接的查询结果为主表中的所有记录,如果从表中有匹配的,则显示匹配的值,如果没有,则显示null
2、左外连接,left join左边的是主表
右外连接,right join右边的是主表
3、左外和右外交换两个表的顺序,可以实现同样的效果
4、全外连接=内连接的结果+表1中有但表2中没有的+表2中有但表1没有的
*/
#查询没有男朋友的女神名
select b.name,bo.* from beauty b left outer join boys bo on b.boyfriend_id=bo.id where bo.id is null;
#查询哪个部门没有员工
#左外
select d.*,e.employee_id from departments d left outer join employees e on d.department_id=d.department_id where e.employee_id is not null;
#右外
select d.*,e.employee_id from employees e right outer join departments d on d.department_id=d.department_id where e.employee_id is not null;
#全外
select b.*,bo.*from beauty b FULL outer JOIN boys bo on b.boyfriend_id=bo.id; #会报错,不支持,结果应该是两表交集
#三、交叉连接
select b.*,bo.* from beauty b cross join boys bo;
#sql92和sql99
功能:sql99支持的较多
可读性: sql99实现连接的条件和筛选条件的分离,可读性较高
mysql自学笔记四(Navicat Premium 15)
最新推荐文章于 2022-02-09 21:00:48 发布