MySQL学习笔记7:join链接查询(SQL 92)

简介

本系列(MySQL学习笔记)是我基于B站上很是受欢迎的MySQL 基础+高级篇- 数据库 -sql -尚硅谷视频所作的笔记,方便你们学习和掌握MySQL。mysql

说明

1.这个系列基本包含了视频中老师讲课的全部内容,包括知识点、案例、部分测试题。
2.所需的配套资料(来自B站评论区)web

@黎曼的猜测:
配套资料下载–>公众号公众号 DragonWell 回复:mysql 注意:是公众号!!是公众号!!是公众号,点那个 搜一搜 搜索!!!
不是私人号,是公众号!!! (能够直接在 搜一搜 搜索 dragonwell) 名称是:DragonWell公众号sql

3.SQLyog的安装(来自B站评论区)数据库

@江左萌粽猪 连接:https://pan.baidu.com/s/18PDjbqEeDSAjQM0VQye6og 提取码:qjuzide

目录

MySQL学习笔记1:select查询(一) 基本用法
MySQL学习笔记2:select查询(二) 条件查询
MySQL学习笔记3:select查询(三) 排序查询
MySQL学习笔记4:常见函数(一) 单行函数
MySQL学习笔记5:常见函数(二) 分组函数
MySQL学习笔记6:group by 分组查询
MySQL学习笔记7:join链接查询(SQL 92标准)svg

链接查询

含义:又称多表查询,当查询的字段来自多个表时,就会用到链接查询
笛卡尔乘积现象:表1有m行,表2有n行,结果m*n行
发生缘由:没有有效的链接条件
如何避免:添加有效的链接条件

分类:
	按年代分类:
	sql92标准:仅仅支持内链接
	sql99标准:【推荐】:支持内链接、外链接(左外和右外)、交叉链接
	
	按功能分类:
	内链接:
		等值链接 
		语法:
			select 查询列表 
			from1 别名,2 别名 
			where1.key1 =2.key2 
			[and筛选条件] 
			[group by 分组字段]
			[having 分组后的筛选]
			[order by 排序字段] 
		非等值链接
		语法:
			select 查询列表 
			from1 别名,2 别名 
			where 非等值链接条件
			[and筛选条件] 
			[group by 分组字段]
			[having 分组后的筛选]
			[order by 排序字段] 
		自链接
		语法:
			select 查询列表 
			from 表 别名1,表 别名2 
			where 等值链接条件
			[and筛选条件] 
			[group by 分组字段]
			[having 分组后的筛选]
			[order by 排序字段] 		
	外链接:
		左外链接
		右外链接
		全外链接
	交叉链接
SELECT * FROM beauty;
SELECT * FROM boys;
SELECT NAME ,boyname FROM beauty,boys; #错误
/* 笛卡尔集的错误状况: #select count(*) from beauty; 输出12行 #select count(*) from boys; 输出4行 最终结果输出48行 由于咱们没有加任何链接条件 */

SELECT NAME,boyname FROM beauty,boys
WHERE beauty.boyfriend_id = boys.id; # 正确

一.sql92标准

1.等值链接

1.等值链接
①多表等值链接的结果为多表的交集部分
②n表链接,至少须要n-1个链接条件
③多表的顺序没有要求
④通常为表起别名
⑤能够搭配全部子句,好比排序、分组、筛选

查询女神名和对应的男神名
SELECT NAME,boyname FROM beauty,boys
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 AS j
WHERE e.`job_id` = j.`job_id`; # job_id字段两个表里都有,有歧义,必须用表名限定

3.两个表的顺序能够调换
SELECT e.last_name,e.job_id,j.job_title 
FROM jobs AS j,employees AS e
WHERE e.`job_id` = j.`job_id`; # job_id字段两个表里都有,有歧义,必须用表名限定
4.能够加筛选
查询有奖金的员工名,部门名,奖金
SELECT e.last_name,d.`department_name`,e.`commission_pct`
FROM employees AS e,departments AS d
WHERE e.`department_id` = d.`department_id` 
AND e.`commission_pct` IS NOT NULL; # 用and链接其余的筛选条件

查询城市名中第二个字符为o的部门名和城市名
SELECT d.department_name,l.`city`
FROM departments AS d,locations AS l
WHERE d.`location_id` = l.`location_id`
AND l.`city` LIKE '_o%';

5.能够加分组
查询每一个城市的部门个数
SELECT COUNT(*),loc.city
FROM departments AS dep,locations AS loc
WHERE dep.`location_id` = loc.`location_id`
GROUP BY loc.city;

查询出有奖金 的每一个部门的部门名、部门的领导编号、该部门的最低工资
SELECT dep.`department_name`,dep.`manager_id`,MIN(e.`salary`)
FROM departments AS dep,employees AS e
WHERE e.`department_id` = dep.`department_id`
AND e.commission_pct IS NOT NULL
GROUP BY e.`department_id`,dep.`manager_id`;

6.能够加排序
查询每一个工种的工种名,员工的个数,按员工个数降序
SELECT job_title,COUNT(*)
FROM jobs AS j,employees AS e
WHERE j.`job_id` = e.`job_id`
GROUP BY job_title
ORDER BY COUNT(*) DESC;

7.实现三表链接
查询员工名、部门名、所在城市
SELECT last_name,department_name,city
FROM employees AS e,departments AS dep,locations AS loc
WHERE e.`department_id`=dep.`department_id` 
AND dep.`location_id`=loc.`location_id`;

2.非等值链接

查询出工资级别为A 的员工的工资和工资级别(grade.sql)
SELECT salary,grade_level
FROM employees AS e,job_grades AS jg
WHERE e.salary BETWEEN jg.lowest_sal AND jg.highest_sal
AND jg.grade_level = 'A';

3.自链接

查询员工名,员工id和其上级的名称,上级id
一张表,找两遍,第一遍找员工的manager_id(员工表),而后(在领导表)找employee_id为manager_id 的就是他的上级
SELECT e.`employee_id`,e.last_name,m.`employee_id`,m.`last_name`
FROM employees AS e,employees AS m # 起两个别名
WHERE e.`manager_id`=m.`employee_id`;

测试题

显示员工表的最大工资,工资平均值
SELECT MAX(salary),AVG(salary) 
FROM employees;

查询员工表的employee_id,job_id,last_name,按department_id降序,salary升序
SELECT employee_id,job_id,last_name
FROM employees
ORDER BY department_id DESC,salary;
查询员工表的job_id 包含a和e 的,而且a在e的前面
SELECT job_id 
FROM employees
WHERE job_id LIKE '%a%e%';
显示当前日期,以及去掉先后空格,截取子字符串
SELECT NOW();
SELECT TRIM(字符 FROM '');
SELECT SUBSTR(str,startIndex);
SELECT SUBSTR(str,startIndex,LENGTH);

做业

显示全部员工的姓名,部门号,部门名称
SELECT last_name,e.department_id,department_name
FROM employees AS e,departments AS d
WHERE e.`department_id` = d.`department_id`;

查询90号部门员工的job_id和90号部门的location_id
SELECT job_id,location_id
FROM employees AS e,departments AS d
WHERE e.`department_id` = d.`department_id`
AND e.`department_id`=90;

选择全部有奖金的员工的last_name department_name,location_id,city
SELECT e.last_name,d.department_name,l.location_id,l.city
FROM employees AS e,departments AS d,locations AS l
WHERE e.`department_id`=d.`department_id` 
AND d.`location_id`=l.`location_id` 
AND e.`commission_pct` IS NOT NULL;

查询每一个工种、每一个部门的部门名、工种名和最低工资
SELECT department_name,job_title,MIN(salary)
FROM departments AS d,jobs AS j,employees AS e
WHERE d.`department_id`=e.`department_id`
AND e.`job_id`=j.`job_id`
GROUP BY department_name,job_title;

查询每一个国家下的部门个数大于2的国家编号
SELECT country_id,COUNT(*)
FROM locations AS l,departments AS d
WHERE l.`location_id`=d.`location_id`
GROUP BY country_id
HAVING COUNT(*)>2;

选择指定员工'Kochhar'的姓名,员工号,以及它的管理者的姓名,员工号
SELECT e.last_name AS 'employees',
e.employee_id AS 'Emp#',
m.last_name AS 'manager',
m.employee_id 'Mgr#'
FROM employees AS e,employees AS m
WHERE e.`manager_id`=m.`employee_id`
AND e.last_name='Kochhar';