语法:select 查询列表 from 表1 别名,表2 别名 where 非等值的连接条件 【and 筛选条件】 【group by 分组字段】 【having 分组后的筛选】 【order by 排序字段】
例1:SELECT e.salary 工资, j.grade_level 工资级别 FROM employees e, job_grades j WHERE e.salary BETWEEN j.lowest_sal AND j.highest_sal;
8.自连接
语法:select 查询列表 from 表 别名1,表 别名2 where 等值的连接条件 【and 筛选条件】 【group by 分组字段】 【having 分组后的筛选】 【order by 排序字段】
例1:查询员工名和上级的名称
SELECT e.last_name 员工名, m.last_name 上级名称 FROM employees e, employees m WHERE e.manager_id = m.employee_id;
内连接
语法:select 查询列表 from 表1 别名 【inner】 join 表2 别名 on 连接条件 where 筛选条件 group by 分组列表 having 分组后的筛选 order by 排序列表 limit 子句;
特点:
表的顺序可以调换
内连接的结果=多表的交集
n表连接至少需要n-1个连接条件
添加排序、分组、筛选
inner可以省略
筛选条件放在where后面,连接条件放在on后面,提高分离性,便于阅读
inner join连接和sql92语法中的等值连接效果是一样的,都是查询多表的交集
1.内连接-等值连接
例1:查询员工名、部门名
SELECT last_name, department_name FROM departments d INNER JOIN employees e ON e.`department_id` = d.`department_id`;
2.内连接-非等值连接
例1:查询员工的工资级别
SELECT e.last_name 员工名, e.salary 薪水, j.grade_level 工资级别 FROM employees e JOIN job_grades j ON e.salary BETWEEN j.lowest_sal AND j.highest_sal;
3.内连接-自连接
例1:查询员工的名字、上级的名字
SELECT e.last_name 员工名, m.last_name 上级名 FROM employees e JOIN employees m ON e.manager_id = m.employee_id;
外连接
语法:select 查询列表 from 表1 别名 left|right|full【outer】 join 表2 别名 on 连接条件 where 筛选条件 group by 分组列表 having 分组后的筛选 order by 排序列表 limit 子句;
应用场景:用于查询一个表中有,另一个表没有的记录
特点:
外连接的查询结果为主表中的所有记录
如果从表中有和它匹配的,则显示匹配的值
如果从表中没有和它匹配的,则显示null
外连接查询结果=内连接结果+主表中有而从表没有的记录
左外连接,left join 左边的是主表
右外连接,right join 右边的是主表
左外和右外交换两个表的顺序,可以实现同样的效果
全外连接=内连接的结果+表1中有但表2没有的+表2中有但表1没有的
1.左外连接
例1:查询哪个部门没有员工
SELECT d.* FROM departments d LEFT JOIN employees e ON d.department_id = e.department_id WHERE e.department_id IS NULL
2.右外连接
例1:查询哪个部门没有员工(调换位置使用RIGHT JOIN)
SELECT d.* FROM employees e RIGHT JOIN departments d ON d.department_id = e.department_id WHERE e.department_id IS NULL
3.全外连接(mysql不支持全外连接)
USE girls; SELECT b.*,bo.* FROM beauty b FULL OUTER JOIN boys bo ON b.`boyfriend_id` = bo.id;
4.交叉连接(交叉联接返回左表中的所有行,左表中的每一行与右表中的所有行组合。交叉联接也称作笛卡尔积。)
SELECT b.*,bo.* FROM beauty b CROSS JOIN boys bo;
八.子查询
1.标量子查询
例1:谁的工资比 Abel 高?
SELECT * FROM employees WHERE salary>( SELECT salary FROM employees WHERE last_name = 'Abel' );
2.列子查询
操作符 含义IN/NOT IN 等于列表中的任意一个
ANY|SOME 和子查询返回的某一个值比较
ALL 和子查询返回的所有值比较
例1:返回location_id是1400或1700的部门中的所有员工姓名
SELECT last_name FROM employees WHERE department_id IN( SELECT DISTINCT department_id FROM departments WHERE location_id IN(1400,1700) );
3.行子查询
例1:查询员工编号最小并且工资最高的员工信息
SELECT * FROM employees WHERE (employee_id,salary)=( SELECT MIN(employee_id),MAX(salary) FROM employees );
4.select后面
例1:查询每个部门的员工个数
SELECT d.*,( SELECT COUNT(*) FROM employees e WHERE e.department_id = d.`department_id` ) 个数 FROM departments d;
5.from后面
例1:查询每个部门的平均工资的工资等级
SELECT ag_dep.*,g.`grade_level` FROM ( SELECT AVG(salary) ag,department_id FROM employees GROUP BY department_id ) ag_dep INNER JOIN job_grades g ON ag_dep.ag BETWEEN lowest_sal AND highest_sal;
6.exists(相关子查询)
例1:查询有员工的部门名
SELECT department_name FROM departments d WHERE EXISTS( SELECT * FROM employees e WHERE d.`department_id`=e.`department_id` );
九.分页查询