当前位置: 首页 > news >正文

MySQL纯代码复习

前言

本文章是用于总结尚硅谷MySQL教学视频的记录文章,主要用于复习,非商用
原视频连接:https://www.bilibili.com/video/BV1iq4y1u7vj/?p=21&spm_id_from=pageDriver&vd_source=c4ecde834521bad789baa9ee29af1f6c

https://www.bilibili.com/video/BV1iq4y1u7vj/?p=21&spm_id_from=pageDriver&vd_source=c4ecde834521bad789baa9ee29af1f6c

该文章记录视频中绝大部分的代码,其中会包夹一些个人表述,适合后续复习使用

文章所用案例表

实际有9张,此处仅仅列出了2张常用表

员工表

在这里插入图片描述

部门表

在这里插入图片描述

其他表

如果用到的时候,会专门放出来的

入门基本语句

最基本的SELECT…FROM结构

我们首先学习以下最基本的SELECT语句,学习结构和一些基本常数查询和虚表了解

#最基本的SELECT语句:SELECT 字段1、字段2...FROM 表名
SELECT 1;#没有任何子句
SELECT 9/2;#没有任何子句

SELECT 1+1
FROM DUAL;#伪表

# *:表中的所有字段(或列)
SELECT*FROM employees;

#查询具体列
SELECT employee_id,last_name,salary
FROM employees;

列的别名_去重_NULL_DESC等操作

在开发中,Java的对象和数据库的对象的命名规则是不一样的,所以需要起别名来改变映射,来适应Java的底层反射,不过在平常的MySQL查询中,别名也是非常常用和实用的操作

列的别名

#列的别名
#查询返回的结果集合称为结果集:resultSet
#它们都可以完成别名效果,但是如果你起的别名是有空格的,则一定要添加''来使用,否则会报错,添加AS则可读性会好一些 
SELECT employee_id AS "emp_id",last_name AS "emp_name",department_id AS "emp_dept_id"
FROM employees;
SELECT employee_id "emp_id",last_name "emp_name",department_id "emp_dept_id"
FROM employees;
SELECT employee_id emp_id,last_name emp_name,department_id emp_dept_id
FROM employees;
SELECT employee_id AS emp_id,last_name AS emp_name,department_id AS emp_dept_id
FROM employees;
#单引号别名也是可以的,但是只是MySQL的不严谨性
#MySQL的varchar字符串应该是单引号,但是双引号也可以,这是MySQL的不严谨,一定要养成使用 别名:双引号 字符串:单引号
INSERT INTO emp
VALUES(1002,"TOM");

在我们只需要知道有哪些分类时,就无需将每个分类都展现出来

去重

#去除重复行
#查询员工表中有哪些部门id
#使用关键字 -> distinct 去重 
SELECT DISTINCT department_id
FROM employees;

在很多编程语言都是有NULL,而NULL通常不可以参与运算,大部分编程语言都是NULL运算等于NULL,Java遇到NULL对象属性也会直接抛出NULL空指针异常…

NULL

#空值参与运算
#1.空值:null
#2.null不等同于0,'','null'
SELECT NULL=0,NULL='',NULL=NULL;#正常情况应该是0或1,但是和NULL运算的结果全部是NULL
#查询奖金率,但是很多员工的奖金率是NULL(没有奖金率)
SELECT * FROM employees;
#查询月工资和年工资 
#控制参与运算:结果一定为空
SELECT employee_id,salary "月工资",salary*(1+commission_pct)*12 "年工资",commission_pct
FROM employees;#错误的演示,因为有了控制运算会让查询结果直接是NULL
#使用了处理NULL的函数来解决问题
#如果字段不是NULL,则是多少就算多少,如果是NULL就用参数2来替换数值
SELECT employee_id,salary "月工资",salary*(1+IFNULL(commission_pct,0))*12 "年工资",commission_pct
FROM employees;#错误的演示,因为有了控制运算会让查询结果直接是NULL

在极少数情况下,我们声明的标识符会和官方定义的关键字重命,这时候再使用就需要添加着重号来告诉MySQL情况了

着重号

#着重号
#着重号一般是用来多表连接时添加的,系统喜欢自动添加着重号,不过最大意义是用来将关键字重名的字段区分为普通字段
#着重号是左上排数字键1的右边的~位置,不按Shift并且是英文状态按该键就是 ` 着重号
CREATE TABLE t(
NAME VARCHAR)
CREATE TABLE t(
`NAME` VARCHAR)
SELECT * FROM ORDER;
SELECT * FROM `ORDER`;

查询常数是使用较少的一种手段

查询常数

#查询常数
#该内容,查询记录有多少条记录,就生成多少条记录
SELECT '宝马三系','落地三十万+',employee_id,last_name
FROM employees;

查看表结构是非常常用的命令,通常用来验证属性的添加、修改等等操作

DESC操作

#显示表结构
#describe是desc的全称,而desc则是缩写,一般都常用desc,因为好拼和少
DESCRIBE employees;#显示了表中字段的详细信息
DESC employees;
DESC departments;
DESCRIBE departments;

使用WHERE过滤数据

在我们实际开发中,不可能总是查询表中所有的记录,这样会浪费大量的物资资源IO也会浪费时间和冗余的数据量,我们总是只需要有意义和有用的数据或内容,所以一个完整的查询一定是要有过滤数据的(除像select*from tableName这种情况)

 #过滤数据
 #基本结构
 #SELECT...FROM...WHERE...
 #查询90号部门员工的信息
 SELECT * 
 FROM employees 
 WHERE department_id = 90;
 #练习:查询last_name为'King'的员工信息
 SELECT *
 FROM employees#MySQL是大小写不敏感的
 WHERE last_name = 'King';

基本SELECT查询课后练习

#基本的SELECT语句的课后练习

#1.查询员工12个月工资的总和,并起别名为ANNUAL SALARY
SELECT employee_id AS "员工号",first_name AS "名",last_name AS"姓",salary*(1+IFNULL(commission_pct,0))*12 AS "ANNUAL SALARY"
FROM employees;
#2.查询employees表中去除重复的job_id以后的数据
SELECT DISTINCT job_id
FROM employees
#3.查询工资大于12000的员工信息和工资
SELECT * 
FROM employees
WHERE salary>12000;
#4.查询员工号为176的员工的姓名和部门号
SELECT * FROM employees
WHERE employee_id = 176;
#5.显示表departments的结构,并查询其中的全部数据
DESC departments;SELECT*FROM departments;

-----------------------------------------------

运算符

算术运算符的使用

在这里插入图片描述

#运算符
#算术运算符: + - * / div % MOD 
SELECT 100,100+0,100-0,100+50,100+50-30,100+35.5,100-35.5#整形和浮点型
FROM DUAL;#虚表
#MySQL的+号没有Java的拼接符的意思,这里是101结果,是底层隐式转换的结果
SELECT 100+'1'
FROM DUAL;
SELECT 100+'a'#此时将'a'看做0处理
FROM DUAL;
SELECT 100+NULL#NULL运算都为NULL
FROM DUAL;
SELECT 100,100*1,100*1.0,100/1.0,100/2,100+2*5/2,100/3,100 DIV 0 #分母如果为0则结果为NULL
FROM DUAL
#取模运算:% mod
SELECT 12%3,12%5,12 MOD -5 ,-12%5,-12%-5
FROM DUAL;
#练习:查询员工id为偶数的员工信息
SELECT employee_id,last_name,salary
FROM employees
WHERE employee_id % 2 = 0;

比较运算符的使用

比较运算符用来对表达式的操作数和右边的操作数进行比较,比较的结果为真则返回1,比较的结果为假则返回0,其他情况则返回NULL
比较运算符经常被用来作为SELECT查询语句的条件来使用,返回适合的条件的结果记录
在这里插入图片描述
在这里插入图片描述

符号运算符

#比较运算符
# = <=> <> != < <= > >=
#如果为真 返回1
#如果为假 返回0
#如果为其他情况 返回NULL
SELECT 1 = 2,1!=2,1='1',1='a',0='a'#和四则运算那个道理一样 'a'不能隐式转换,所以是0
FROM DUAL;
#两边都是字符串的话,则按照ANSI的比较规则进行比较
SELECT 'a'='a','ab'='ab','a'='b'
FROM DUAL;
SELECT 1=NULL,NULL=NULL #只要有null参与判断,结果就为null
FROM DUAL;
SELECT last_name,salary
FROM employees
#where salary = 6000;
WHERE commission_pct = NULL;#不会有任何结果
#<=>:安全等于->为NULL而生
SELECT 1<=>2,1<=>'1',1<=>'a',0<=>'a'
FROM DUAL;
SELECT 1<=>NULL,NULL<=>NULL#结果0 1,当有NULL时结果是0,所以0=0
FROM DUAL;	
SELECT last_name,salary,commission_pct
FROM employees
WHERE commission_pct <=> NULL;
SELECT 3<>2,'4'<>NULL,''!=NULL,NULL!=NULL
FROM DUAL;

非符号运算符

在这里插入图片描述

第一波

#非符号运算符
#IS NULL\IS NOT NULL\ISNULL
#练习:查询表中commission_pct为null的数据有哪些
SELECT last_name,salary,commission_pct
FROM employees
WHERE commission_pct IS NULL;和安全等于是一模一样的
#或
SELECT last_name,salary,commission_pct
FROM employees
WHERE ISNULL(commission_pct);

#练习:查询表中commission_pct不为null的数据有哪些
SELECT last_name,salary,commission_pct
FROM employees
WHERE commission_pct IS NOT NULL;#只查询不为NULL的数据
#或
SELECT last_name,salary,commission_pct
FROM employees
WHERE NOT commission_pct <=> NULL;

第二波

#LEAST()\GREATEST least greatest
SELECT LEAST('g','b','t','m'),GREATEST('g','b','t','m')#比较的是字母的顺序a-z
FROM DUAL;
#length -> 字符长度(个数)
SELECT LEAST(first_name,last_name),LEAST(LENGTH(first_name),LENGTH(last_name))
FROM employees;
#BETWEEN...AND
#查询工资在6000到8000的员工信息
![SELECT employee_id,last_name,salary#between...and...
FROM employees](https://img-blog.csdnimg.cn/a93673db92764747adb2f8525cafc7a1.png)

#&&\AND:且 | or:或 | NOT:非 
#where salary BETWEEN 6000 AND 8000;包括边界值
#WHERE salary >=6000 && salary<=8000;
WHERE salary >=6000 AND salary<=8000;#不要放过来写,会直接无结果的
#查询工资不在6000-8000的员工信息
SELECT employee_id,last_name,salary#between...and...
FROM employees
#WHERE salary <6000 or salary > 8000;
WHERE NOT salary BETWEEN 6000 AND 8000;#包括边界值
#in(set)\not in(set)
#连习:查询部门为10,20,30部门的员工信息
SELECT last_name,salary,department_id
FROM employees
WHERE department_id IN(10,20,30);#如果用 10 OR 20 OR 30是不靠谱的 因为20和30非0就看成1了,全都要了 所以要改为。department_id=20...	
#练习:查询工资不是6000,7000,8000的员工信息
SELECT last_name,salary
FROM employees
WHERE NOT salary IN(6000,7000,8000);
#where salary NOT in(6000,7000,8000);

#LIKE:模糊查询
#练习:查询last_name中包含字符'a'的员工信息
SELECT last_name,first_name,salary
FROM employees
#如果是 'a%'那就表示名字以a开头的员工,如果是'%a'就表示名字以a结束的员工,其他的依次根据情况类推...
WHERE last_name LIKE '%a%';#忽略了大小写;'%a%'	%表示前面有不确定个数的字符,%表示后面有不确定个数的字符

#练习last_name中包含字符'a'且包含字符'e'的员工信息
SELECT last_name,salary
FROM employees
#where last_name like '%a%' and last_name LIKE '%e%';
WHERE last_name LIKE '%a%e%' OR last_name LIKE '%e%a%';

#_:代表一个不确定的字符
#练习:查询第三个字符是'a'的员工信息
SELECT last_name
FROM employees
WHERE  last_name LIKE '__a%';#中间不要加空格

#练习:查询第二个字符是_且第三个字符串是'a'的员工信息
#需要使用转义字符:\
SELECT last_name 
FROM employees
WHERE last_name LIKE '_\_a%';
#或者(了解)
SELECT last_name 
FROM employees
WHERE last_name LIKE '_$_a%' ESCAPE '$';#自定义转义字符 默认是斜线\表示转义

第三波

#REGEXP\RLIKE:正则表达式
#1:该字符串是否以s开头? 1
#2:该字符串是否以t结尾? 1
#3:该字符串是否包含hk? 1
SELECT 'shkstart' REGEXP '^s','shkstart' REGEXP 't$','shkstart' REGEXP 'hk'
FROM DUAL;
#1:是否包含gu?gu 中间有一个不确定的字符 1
#如果是 gu..gu 则是 0
#2:该字符串是否包含a或者包含b
SELECT 'atguigu' REGEXP 'gu.gu','atguigu' REGEXP '[ab]'
FROM DUAL;

在这里插入图片描述

逻辑运算符与位运算符的使用

#逻辑运算符:OR || AND && NOT !XOR

#or and
SELECT employee_id,last_name,salary#between...and...
FROM employees
#WHERE department_id = 10 OR department_id = 20;#和IN一样
#在大部分情况下 尤其是唯一标识的字段属性,是绝对不应该满足2个相同记录类型条件的
#WHERE department_id = 10 AND department_id = 20;#既是10号部门又是20号部门,这样是不合理的是不会有结果的
WHERE department_id = 50 AND salary >6000;#此处是针对该表记录不同属性的查询 没有问题
#not
SELECT employee_id,last_name,salary#between...and...
FROM employees
#WHERE salary not between 6000 and 8000;查询工资不再6000和8000区间内的员工信息
#where commission_pct is NOT null;查询奖金率不为空的员工,如果去掉NOT 就是查询为NULL的
WHERE NOT commission_pct <=> NULL;#安全等于 不为NULL
#XOR
SELECT employee_id,last_name,salary
FROM employees
#如果工资大于6000 则一定没有50号部门
#如果是500部门则工资一定没有大于6000
WHERE department_id = 50 XOR salary > 6000;

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

运算符练习

#1.选择工资不在5000到12000的员工的姓名和工资
SELECT employee_id,last_name,salary
FROM employees
#where salary not between 5000 AND 12000;
WHERE salary < 5000 OR salary > 12000;
#2.选择在20或50号部门的员工姓名和部门号
SELECT employee_id,last_name,salary,department_id
FROM employees
#WHERE department_id IN(20,50);
WHERE department_id = 20 OR department_id = 50;
#3.选择公司中没有管理者的员工姓名及job_id
SELECT employee_id,last_name,job_id
FROM employees
WHERE manager_id IS NULL;
#4.选择公司中有奖金的员工姓名、工资和奖金级别
SELECT last_name,salary,commission_pct
FROM employees
WHERE commission_pct  IS NOT NULL;
#5.选择员工姓名的第三个字母是a的员工姓名
SELECT last_name
FROM employees
WHERE last_name LIKE '__a%';
#6.选择姓名中有字母a和k的员工姓名
SELECT last_name
FROM employees
#WHERE last_name LIKE '%a%' AND last_name LIKE '%k%';
WHERE last_name LIKE '%a%k%' OR last_name LIKE '%k%a%';
#7.显示出表employees表中first_name以'e'结尾的员工信息
SELECT first_name
FROM employees
WHERE first_name LIKE '%e';
#正则表达式
SELECT first_name
FROM employees
WHERE first_name REGEXP 'e$';#以e开头的写法:'^e'
#8.显示出表employees部门编号在 80-100之间的姓名、工种
SELECT last_name,job_id
FROM employees
#方式一:推荐
#where department_id between 80 AND 100;
#方式二:相同效果
#where department_id >=80 and department_id <=100;
#方式三:仅仅适用于这个区间只有这三个值的表
WHERE department_id IN (80,90,100);
#9.显示出表employees的manager_id 是100,101,110的员工的姓名、工资、管理者
SELECT employee_id,salary,manager_id
FROM employees
WHERE manager_id IN (100,101,110);

-----------------------------------------------

排序与分页

该内容是查询内容之一
在这里插入图片描述

ORDER BY实现排序操作

ORDER BY排序操作

#查询与排序
#排序
SELECT * FROM employees; #如果没有使用排序操作,则默认顺序是先后添加的顺序显示的
#练习:按照salary从高到底的顺序去显示员工信息
#使用ORDER BY 对查询得到的数据进行排序操作 
#ORDER -> 排序 BY-> 使用...或用...
#升序:ASC(ascend)
#降序:DESC(descend)
SELECT employee_id,last_name,salary 
FROM employees
ORDER BY salary DESC;#使用salary进行排序,DESC ->倒序 ASC->正序, 默认正序ASC 
#我们可以使用列的别名,进行排序
#列的别名只能在order by 中使用,不能在WHERE中使用
#因为执行顺序:先看来自哪个表、然后看过滤条件,然后才是看要哪些数据
#先过滤再查条件,这样做可以提升效率等等,所以WHERE要早执行,是看不到别名的
SELECT employee_id,salary*12 annual_sal
FROM employees
#WHERE annual_sal > 10000
ORDER BY annual_sal;
#因为先过滤后查询所选字段,所以就出现了排序数据里只有 50 60 70的情况
#强调格式:WHERE必须写在FROM之后和ORDER BY 之前
SELECT employee_id,salary,department_id
FROM employees
WHERE department_id IN(50,60,70)
ORDER BY department_id DESC;

二级排序
在很多时候,有些事物都满足一个条件,比如价格…其中规格之一参数…
那么在这个时候就要出现第二个条件、第三个条件、…
所以也就有了二级排序、三级排序、…
内容并不多,不过也是后续实现业务层等等时的重要操作,尤其是像DAO层传输数据给Service层,然后Service再传输给Controller,控制器通过Tomcat服务器将数据传给浏览器,Thymeleaf再将数据渲染到页面上等等…

#二级排序
#练习:显示员工信息,按照department_id的降序排列,salary的升序排列
SELECT employee_id,salary,department_id
FROM employees
ORDER BY department_id DESC,salary ASC;#用逗号隔开,写后面的条件(等级排序)

LIMIT实现分页

在浏览器上,我们并不会将从数据库获取的数据全部都呈现在用户眼前,这样即冗余又会增加服务器后端的负压,而通过分页来进行部分分页或者异步操作(SpringMVC的ajx->vue内容)等等,所以我们需要通过分页来进行有限制的传输数据数量
在这里插入图片描述

#分页
#mysql使用limit实现数据的分页显示
#需求1:每页显示20条记录,此时显示第1页
SELECT employee_id,last_name
FROM employees
LIMIT 0,20;#0:偏移量,20:每页数据量
#需求2:每页显示20条记录,此时显示第2页
SELECT employee_id,last_name#
FROM employees
LIMIT 20,20;
#需求:每页显示pageSize条件记录,此时显示第pageNo页
#公式:LIMIT (pageNo-1) * pageSize,pageSize;
#LIMIT的格式:严格来说:LIMIT 位置偏移量,条目数
#结构"LIMIT 0,条目数" 等价于 "LIMIT 条目数"
#WHERE ... ORDER BY ...LIMIT声明顺序如下
SELECT employee_id,last_name,salary
FROM employees
WHERE salary>6000
ORDER BY salary DESC
LIMIT 10;
#练习:表里有107条数据,我们只想要显示第32、33条数据怎么办呢?
SELECT employee_id,last_name,salary
FROM employees
LIMIT 31,2;#31:从哪里开始... 2:条目数

#MySQL8.0新特性:LIMIT ... OFFSET ...
#练习:表里有107条数据,我们只想要显示第32、33条数据怎么办呢?
SELECT employee_id,last_name,salary
FROM employees
LIMIT 2 OFFSET 31;
#LIMIT 31 OFFSET 2;新特性将两者顺序颠倒了一下,使用上了关键字,可能可读性会更好一些

#练习:查询员工工资中最高的员工信息
SELECT employee_id,last_name,salary
FROM employees
ORDER BY salary DESC
#LIMIT 0,1;
LIMIT 1;

扩展
在这里插入图片描述
在这里插入图片描述

排序与分页练习

下一步就是多表查询了,大的要来了!!!
练习的内容也是比较简单的,可以一步一步的向下写,在后续的多表查询和子查询时,就要局部思考的去写了!

#排序与分页的练习
#1.查询员工的姓名和部门号和年薪,按年薪降序,按姓名升序显示
SELECT last_name,department_id,(salary*12) AS "annual_sal"
FROM employees
ORDER BY annual_sal DESC,last_name ASC;#默认升序,可以不写ASC,但是倒序必须写 DESC
#2.选择工资不在8000到17000的姓名和工资,按照工资降序,显示第21到40的位置
SELECT employee_id,last_name,salary
FROM employees
WHERE salary NOT BETWEEN 8000 AND 17000
ORDER BY salary DESC
LIMIT 20,20
#3.查询邮箱中包含e的员工信息,并先按邮箱的字节顺序降序,再按部门升序
SELECT employee_id,last_name,salary
FROM employees
#where email LIKE '%e%'
WHERE email REGEXP '[e]'
ORDER BY LENGTH(email) DESC,department_id ASC;

-----------------------------------------------

多表 查询

多表查询是MySQL的整个核心内容,非常考验自己对SQL语句的功底和对表结构等的理解和掌握程度,不过,不要害怕,只要自己认真学,真正写起来的时候其实也没有什么难度的

为什么需要多表查询

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

#多表查询
#查询员工名为'Abel'的人在哪个城市工作?
SELECT*
FROM employees
WHERE last_name = 'Abel';#部门id为80

SELECT*
FROM departments
WHERE department_id = 80;#可以看出部门为销售,城市id为2500(坐落地域)

SELECT *
FROM locations
WHERE location_id = 2500;
#通过上面三次查询,我们才知道该员工的部门号和工作城市

笛卡尔积的错误与正确的多表查询

笛卡尔积错误演示
在这里插入图片描述

#多表的查询如何实现?
#出现笛卡尔积错误
#笛卡尔积代表 x*y条记录,相当于手拉手问题,都结合运算了一次
#2889条记录 --> (employees)107*27(departments)
SELECT employee_id,department_name
FROM employees,departments;

在这里插入图片描述

正确的多表连接
我们在进行多表连接查询时,应该有连接过滤条件的,并且是表1和表2有大致相等的字段所关联,才能有条有序的展现出来

#正确的多表连接条件
SELECT employee_id,department_name
FROM employees,departments
#两个表的连接条件
WHERE employees.department_id = departments.`department_id`;
#106条数据,在员工表中有一人没有部门,所以只展现了106条数据

在这里插入图片描述
扩展内容
在这里插入图片描述

#下面语句是错误的,因为两个表都有department_id
#系统无法分析出到底是表1还是表2
SELECT employee_id,department_name,department_id
FROM employees,departments
#两个表的连接条件
WHERE employees.department_id = departments.`department_id`;
#----------------------------------------------------------------
#正确示范
#如果查询语句中出现了多个表中都存在的字段,则必须指明此字段所在的表
SELECT employee_id,department_name,employees.department_id
FROM employees,departments
#两个表的连接条件
WHERE employees.department_id = departments.`department_id`;
#建议:从sql优化角度来看,建议多表查询时,每个字段前都指明其所在的表
SELECT employees.employee_id,departments.department_name,employees.department_id
FROM employees,departments
#两个表的连接条件
WHERE employees.department_id = departments.`department_id`;
#问题:指明的表名太长,有些太冗余怎么办?
#我们可以为表起别名,但是如果一旦起了别名,在查询和WHERE中就只能用这个别名
#原因是执行顺序,先FROM 然后WHERE 然后SELECT...的原因
SELECT emp.employee_id ,dept.department_name,emp.department_id
FROM employees emp,departments dept#别名会覆盖掉原表名
#两个表的连接条件
WHERE emp.department_id = dept.`department_id`;
#如果有n个表实现多表查询,则需要n-1个连接条件
#练习:查询员工的employee_id,last_name,department_name,city
SELECT emp.employee_id,emp.last_name,dept.department_name,locat.city
FROM employees emp,departments dept,locations locat
WHERE emp.`department_id` = dept.`department_id` 
AND dept.`location_id` = locat.`location_id`;#三个表都需要连接在一起,一一对应

等值连接VS非等值连接、自连接VS非自连接

等值连接VS非等值连接

#多表查询的分类
/*
角度1:等值连接 VS非等值连接

角度2:自连接 VS 非自连接

角度3:内连接 VS 外连接
*/
#等值连接 VS 非等值连接
#非等值连接的例子
SELECT*FROM job_grades;
#往常像员工表和部门表的emp.department_id = dept.department_id就是等值连接
SELECT e.last_name,e.salary,j.grade_level
FROM employees e,job_grades j
#where e.`salary` between j.`lowest_sal` and j.`highest_sal`;
WHERE e.salary>=j.`lowest_sal` AND e.salary <=j.`highest_sal`
ORDER BY j.grade_level ASC;

自然连接VS非自然连接

#自连接 VS 非自连接
#非自连接无非就是引用了外表的关联(连接字段)属性
#练习:查询每个员工的管理者
SELECT emp1.`employee_id`,emp1.`last_name`,emp2.`employee_id`,emp2.`last_name`
FROM employees emp1,employees emp2
WHERE emp1.`manager_id` = emp2.`employee_id`;

SQL92与99语法如何实现内连接和外连接

满足查询连接条件的结果集记录都被称为内连接,而不满足的就是外连接,有些时候,我们反而需要查询那些满不足条件的记录
在这里插入图片描述

在这里插入图片描述

#内连接 VS 外连接
#内连接:合并具有同一列的两个以上的表的行,结果集中不包含一个表与另一个表不匹配的行
SELECT e.`employee_id`,d.`department_name`
FROM employees e,departments d
WHERE e.`department_id` = d.`department_id`;#106行
#如果想要将不符合查询条件的记录就叫外连接
#外连接:合并具有同一列的两个以上的表的行,结果集中除了包含一个表与另外一个另匹配的行之外
#还查询到了左表或右表中不匹配的行,也就是 107条
#外连接的分类:左外连接、右外连接、满外连接(都要)
#左外连接;两个表在连接过程中除了返回满足连接条件的行以外还返回左表中不满足条件的行
#右外连接;两个表在连接过程中除了返回满足连接条件的行以外还返回右表中不满足条件的行

#练习:查询所有员工的last_name,department_name信息(所有的,一定是外连接!)
SELECT e.`employee_id`,d.`department_name`
FROM employees e,departments d
WHERE e.`department_id` = d.`department_id`;#107行(包括了没有部门信息的员工信息——106+1条)
#SQL92语法实现内连接:见上,略
#SQL92语法实现外连接:使用+   	--------------MySQL不支持SQL92语法中外连接的写法!
SELECT e.`employee_id`,d.`department_name`
FROM employees e,departments d
WHERE e.`department_id` = d.`department_id`(+);
#SQL99语法中使用JOIN...ON的方式实现多表查询。这种方式也能解决外连接的问题。MySQL是支持此种方式的
SELECT e.`employee_id`,d.`department_name`
FROM employees e JOIN departments d#普通内连接
ON e.`department_id` = d.`department_id`;#106条
#上次多表查询的实例
SELECT e.`employee_id`,d.`department_name`#INNER可以省略 表示内连接
FROM employees e INNER JOIN departments d#普通内连接
ON e.`department_id` = d.`department_id`
JOIN locations l
ON d.`location_id` = l.`location_id`;
SELECT e.`employee_id`,d.`department_name`
FROM employees e LEFT JOIN departments d#左外连接 指包含左表不符合条件的记录
ON e.`department_id` = d.`department_id`;#107条

SELECT e.`employee_id`,d.`department_name`
FROM employees e RIGHT JOIN departments d#右外连接 指包含左表符合条件的记录
ON e.`department_id` = d.`department_id`;#122条

#SQL99语句实现外连接
#练习:查询所有的员工last_name,department_name信息
SELECT last_name,department_name#OUTER表示外连接 OUTER可以省略
FROM employees t1 LEFT OUTER JOIN departments t2#左外连接
ON t1.`department_id` = t2.`department_id`;

#右外连接
SELECT last_name,department_name#OUTER表示外连接 OUTER可以省略
FROM employees t1 RIGHT OUTER JOIN departments t2#右外连接
ON t1.`department_id` = t2.`department_id`;

#满外连接
SELECT last_name,department_name#OUTER表示外连接 OUTER可以省略
FROM employees t1 FULL OUTER JOIN departments t2#全外连接,但是MySQL不支持这么写
ON t1.`department_id` = t2.`department_id`;

使用SQL99实现7种JOIN操作

内连接
左外连接
右外连接
全外连接
左+右外连接
只要左连接
只要右连接
这里左右说的是不满足条件的外连接,内连接是满足条件的连接,左外就是左+内,右外是右+内,全就是三者结合,也可以单个,比如内 、左、右,其实挺好理解的,知道上面图里,中间是内连接的内容就很好理解其他的连接含义!
P29

附录

在这里插入图片描述

相关文章:

  • 【浅学Linux】动态库与静态库的封装与使用
  • [ITIL]-ITIL4的服务管理关键概念
  • 第15届台州学院校赛题解
  • Vue3树形控件实现跳转页面
  • C++-字符串处理函数-查找-截取-分割-替换-删除-格式化-与数值互转-拼接-正则表达式-常用功能
  • LeetCode 790. 多米诺和托米诺平铺
  • Qt基础之四:Qt信号与槽机制原理及优缺点
  • 机器学习笔记 十七:基于Gini Importance、Permutation Importance、Boruta的随机森林模型重要性评估的比较
  • 大数据ClickHouse进阶(二十七):ClickHouse服务监控
  • 02 【nodejs开发环境安装】
  • 【Designing ML Systems】第 2 章 :机器学习系统设计简介
  • C++与C语言中的字符串
  • 8. 无线体内纳米网:基于蓝牙LE接口的数字ID系统
  • 极智AI | 昇腾 CANN ATC 模型转换
  • 富文本编辑器(添加列表)
  • 格理论与密码学-2-2-公钥密码体制和哈希函数
  • Vue框架的学习(Vue操作指令学习三 V-bind )第三课
  • C语言之指针(中)
  • neo4j-jdbc-driver这个坑货
  • 云存储系统架构及优势