MySQL基本查询

MySQL基本查询

  • 表的增删查改
  • Create(增)
  • Retrieve(查)
    • select列
      • 全列查询
      • 指定列查询
      • 查询字段为表达式
      • 为查询结果指定别名
      • 结果去重
    • where 条件
      • 英语不及格的同学的英语成绩
      • 语文成绩在 [80, 90] 分的同学及语文成绩
      • 数学成绩是 58 或者 59 或者 98 或者 99 分的同学及数学成绩
      • 姓孙的同学
      • 孙某同学
      • 语文成绩好于英语成绩的同学
      • 总分在 200 分以下的同学
      • 语文成绩 > 80 并且不姓孙的同学
      • 孙某同学,否则要求总成绩 > 200 并且 语文成绩 < 数学成绩 并且 英语成绩 > 80
    • 结果排序
      • 同学及数学成绩,按数学成绩升序显示
      • 同学及 qq 号,按 qq 号排序显示
      • 查询同学各门成绩,依次按 数学降序,英语升序,语文升序的方式显示
      • 查询同学及总分,由高到低
      • 查询姓孙的同学或者姓曹的同学数学成绩,结果按数学成绩由高到低显示
    • 筛选分页结果
      • 按 id 降序进行分页,每页 3 条记录,分别显示 第 1、2、3 页
  • update(改)
      • 将孙悟空同学的数学成绩变更为 80 分
      • 将曹孟德同学的数学成绩变更为 60 分,语文成绩变更为 70 分
      • 将总成绩倒数前三的 3 位同学的数学成绩加上 30 分
      • 将所有同学的语文成绩更新为原来的 2 倍
  • delete(删)
      • 删除孙悟空同学的考试成绩
      • 删除整张表数据
    • 截断表
  • 插入查询结果
      • 删除表中的的重复复记录,重复的数据只能有一份
  • 聚合函数
    • 什么是聚合函数?
    • MySQL常见聚合函数
      • 统计班级共有多少同学
      • 统计班级收集的 qq 号有多少
      • 统计本次考试的数学成绩分数个数
      • 统计本次考试去重过后的数学成绩分数个数
      • 统计数学成绩总分
      • 统计平均总分
      • 返回英语最高分
      • 返回 > 70 分以上的数学最低分
  • group by子句的使用
    • 测试案例
      • 显示每个部门的平均工资和最高工资
      • 显示每个部门的每种岗位的平均工资和最低工资
      • 显示平均工资低于2000的部门和它的平均工资

表的增删查改

CRUD : Create(创建), Retrieve(读取),Update(更新),Delete(删除)

Create(增)

语法:
insert into tablename [(colname1,colname2…)] values(num1,num2,…);
eg:
先创建一个表,然后再向表里面插入数据:
MySQL基本查询_第1张图片
然后向里面插入数据(正常插入:
MySQL基本查询_第2张图片
上面的插入方式,是按照指定列的方式来进行插入的,我们在插入的时候,可以不用指定要插入那些列的名字,而直接插入值,这时候这种插入方式叫做 ‘全列插入’:
MySQL基本查询_第3张图片
当然我们也可以指定某些列的插入顺序,比如我就是要先插入年龄,在插入姓名、学号、性别,可以吗?当然可以:
MySQL基本查询_第4张图片
对于可以缺省的,我们在插入的时候也可以不显示指定进行插入,比如本例中id是可以缺省的、性别、年龄也是可以缺省的,那么我们在插入的时候就可以不显示指定性别、id、年龄进行插入:
MySQL基本查询_第5张图片
如果我们想一次性插入多行数据可以吗?
当然可以:
多行插入:
MySQL基本查询_第6张图片
如果还想要插入更多行数据,直接添加多行数据即可:
MySQL基本查询_第7张图片

一般情况下,我们插入主键或唯一键重复的数据时,数据会告诉我们键值冲突,为此我们会插入失败:
MySQL基本查询_第8张图片
但是我们就是要插入values(‘司马光’,9,‘男’,90)这行数据怎么办?
我们可以利用语法:

insert ..... on duplicate key update colname1=xxx,colname2=yyy.....
on duplicate key:如果发生键值冲突
这句话的意思就是:如果当前插入的数据发生键值冲突,那么就将发生键值冲突行的数据更新为后面的数据:
比如上例中我们就是要插入:values(‘司马光’,9,‘男’,90)这行数据1,MySQL语句就可以这样写:
insert into students values('司马光',9,'男',90) on duplicate key update name='司马光',age=90,sex='男';
效果如图:
MySQL基本查询_第9张图片
替换:
如果发生键值冲突,那么就将冲突行数据替换成后续的数据;
如果没有发生键值冲突,那么就不发生替换,直接进行插入;
语法:
replace into tablename (colname1,colname2,...) values(x1,x2,...)
eg:
MySQL基本查询_第10张图片
MySQL基本查询_第11张图片

Retrieve(查)

select列

语法:
SELECT [DISTINCT] {* | {column [, column] ...} [FROM table_name] [WHERE ...] [ORDER BY column [ASC | DESC], ...] LIMIT ...
eg:
创建表结构:
MySQL基本查询_第12张图片
然后向里面插入一些数据:
MySQL基本查询_第13张图片

全列查询

如果我们要查询所有列的属性的话,我们可以按照以下方式:
select colnam1,colname2,..... from tablename;
对应本例中就是:
select id,name,chinese,math,english from exam_result;
MySQL基本查询_第14张图片
但是这样查询所有列的话比较麻烦,要写出所有列的名称,为了简单,我们可以利用 ‘*’ 这个通配符来表示所有列,为此我们查询所有列的语句就可以变为:
select * from tablename;
eg:
MySQL基本查询_第15张图片
但是在实际使用使用中,我们不建议直接使用全列查询,因为实际的数据库可能很大,我们使用全列查询的话,很可能导致我们的电脑刷屏,观察数据也不太清楚,其次,如果我们使用全列查询的话,就意味着我们需要使用更多的网络资源来进行传输数据;

指定列查询

指定列查询,顾名思义就是查询指定列的数据,没有显示指定查询的就不会显示:
eg:
MySQL基本查询_第16张图片
指定列的数据不一定按照定义表的顺序来;

查询字段为表达式

  1. 表达式不包含任何列字段:
    MySQL基本查询_第17张图片
    对于不包含任何列字段的表达式,在最后打印的时候会新增一列然后原样输出;
  2. 表达式包含一个列字段:
    MySQL基本查询_第18张图片
    数据库会自动将表达式计算过后再输出;
    (对于上述SQL语句的理解:读取id字段、name字段、语文成绩+10字段从exam_result表中)
  3. 表达式中包含多个列字段:
    MySQL基本查询_第19张图片
    (对于上述SQL语句的理解:读取id字段、name字段、三科总和字段从exam_result表中);

为查询结果指定别名

语法:
select colname1 [as] newcolname1,colname2 [as] newcolname2... from tablename
eg:
MySQL基本查询_第20张图片

结果去重

语法:
select distinct colname from tablename;
eg:
MySQL基本查询_第21张图片

where 条件

在MySQL中where就相当于C/C++语言中的if语句;

比较运算符:

运算符 说明
>,>=,<,<= 大于,大于等于,小于,小于等于
= 等于(注意不是赋值),null不安全,也就是说=不能参与null的比较,比如:null=null的结果是null,1=null的结果也是null,而不是布尔值
<=> 等于,null是安全的也就是说<=>可以参与null的比较,比如:null<=>null,结果是1;1<=>null,结果是0;也就是说如果参与等于运算的数据中可能含有null,我们建议用<=>来比较;
!=,<> 这两个不等于符号对于null来说都是不安全的,!=,<>都不能参与null的比较,比如:null!=null or null<>null 结果都是null;1!=null or 1<> null 结果都是null;
between a0 and a1 范围匹配,[a0,a1],如果a0<=value<=a1,则返回true(1)
in(option…) value是option中的任意一个返回true(1)
is null value 是null?是,返回true(1)
is not null value 不是是null吗?不是,返回true(1)
like 模糊匹配.%表示任意多个字符(包括0个),_表示任意一个字符

逻辑运算符:

运算符 说明
and 逻辑与
or 逻辑或
not 逻辑取反

英语不及格的同学的英语成绩

分析:
需要读取的列:
姓名、英语成绩;
帅选条件:英语成绩<60;
SQL语句:
select name,english from exam_result where english < 60;
MySQL基本查询_第22张图片

语文成绩在 [80, 90] 分的同学及语文成绩

分析:
需要读取的列:
姓名、语文成绩;
筛选条件: chinese大于等于80并且小于等于90;
SQL语句:
select name ,chinese from exam_result where chinese>=80 and chinese<= 90;
MySQL基本查询_第23张图片
SQL语句还可以这样写:
select name,chinese from exam_result where chinese between 80 and 90;
MySQL基本查询_第24张图片

数学成绩是 58 或者 59 或者 98 或者 99 分的同学及数学成绩

分析:
需要读取的列:
姓名、数学成绩;
筛选条件:数学成绩是 58 或者 59 或者 98 或者 99 分;
SQL语句:
select name,math from exam_result where math=58 or math=59 or math=98 or math=99;
MySQL基本查询_第25张图片
SQL语句还可以这样写:
select name,math from exam_result where math in(58,59,98,99);

MySQL基本查询_第26张图片

姓孙的同学

分析:
需要读取的列:
姓名
筛选条件:姓孙的同学;
SQL语句:
select name from exam_result where name like '孙%';
MySQL基本查询_第27张图片

孙某同学

分析:
需要读取的列:
姓名
筛选条件:孙某
SQL语句:
select name from exam_result where name like '孙_';
MySQL基本查询_第28张图片

语文成绩好于英语成绩的同学

分析:
需要读取的列:
姓名、语文成绩、数学成绩;
筛选条件:语文成绩大于英语成绩
SQL语句:
select name,chinese,english from exam_result where chinese>english;
MySQL基本查询_第29张图片

总分在 200 分以下的同学

分析:
需要读取的列:
姓名、总分
筛选条件:总分<200
SQL语句:
select name,english+chinese+math from exam_result where english+chinese+math<200;
MySQL基本查询_第30张图片
注意:
这里不能向以下这样写:
select name,english+chinese+math as 总分 from exam_result where 总分<200;
在这里插入图片描述
这样写是会报错的,报错原因是因为数据库不认识 ‘总分’ 这个字符,为什么呢?我们不是已经在前面已经将english+chinese+math重命名为 ‘总分’ 了嘛?按理来说 ‘总分’ 这个标识就等价于 english+chinese+math 啊,为什么还会报错?这就与MySQL执行的顺序先后相关了,在MySQL中是先执行读取操作操作在执行筛选操作?还是先执行筛选操作再执行读取操作?
很明显是先执行的筛选操作,MySQL在第一次遍历的时候就带着筛选条件来进行遍历的,这一次遍历就能拿到最后的结果!而如果我们是先遍历,再在遍历结果过中进行筛选的话,那么就会进行两次遍历,很明显存在浪费!因此MySQL选择那种方式就显而易见了,既然是先使用的筛选条件,可是筛选条件为 ‘总分’ < 200 这个’总分’并不存在于数据库列中啊,自然就报未知列名错误!我们这是属于先使用后重命名,数据库不认识是很正常的!

语文成绩 > 80 并且不姓孙的同学

分析:
需要读取的列:
姓名、语文成绩
筛选条件:语文成绩大于80并且不姓孙;
SQL语句:
select name,chinese from exam_result where chinese > 80 and (not (name like '孙%'));

MySQL基本查询_第31张图片

孙某同学,否则要求总成绩 > 200 并且 语文成绩 < 数学成绩 并且 英语成绩 > 80

分析:
需要读取的列:
姓名、语文成绩、数学成绩、英语成绩、总成绩;
筛选条件: 孙某同学 或者 总成绩 > 200 并且 语文成绩 < 数学成绩 并且 英语成绩 > 80
SQL语句:
select name,chinese,math,english ,math+chinese+english from exam_result where name like '孙_' or (math+chinese+english >200 and chinese 80);
在这里插入图片描述

结果排序

语法:
ASC:升序
DESC:降序
默认升序
select ... from tablename [where] order by colname [ASC|DESC];
注意:没有order by的语句返回的结果是未定义的,永远不要依赖,尽管它看起来有序!
测试表结构:
MySQL基本查询_第32张图片
测试表中数据:
MySQL基本查询_第33张图片

同学及数学成绩,按数学成绩升序显示

分析:
需要读取列:
姓名、数学成绩
筛选条件:无
排序:以数学成绩排升序
SQL语句:
select name,math from exam_from order by math ASC;
MySQL基本查询_第34张图片

同学及 qq 号,按 qq 号排序显示

分析:
需要读取的列:
姓名、qq;
筛选条件:无;
排序:以qq号为升序或者降序;
SQL升序语句:
select name,qq from exam_result order by qq ASC;
MySQL基本查询_第35张图片
我们可以发现null值比任何值都小,因此被排在最上面!
SQL降序语句:
select name,qq from exam_result order by qq DESC;
MySQL基本查询_第36张图片
我们可以发现,null比任何值都要小,因此被排在最小面;

查询同学各门成绩,依次按 数学降序,英语升序,语文升序的方式显示

分析:
需读取的列:
姓名、数学成绩、英语成绩、语文成绩
筛选条件:无
排序:依次按 数学降序,英语升序,语文升序
SQL语句:
select name,math,english,chinese from exam_result order by math DESC ,english ASC,chinese ASC;
MySQL基本查询_第37张图片
这个的应用场景就是:
首先按照数学成绩排序数学成绩高的排前面,数学成绩相等,则看英语成绩,英语成绩小的排前面,如果英语成绩还想等,则看语文成绩,语文成绩小的排前面,如果语文成绩还想等,看程序员自己的控制!

查询同学及总分,由高到低

分析:
需读取的列:
姓名、总分
筛选条件:无
排序:按总分降序
SQL语句:
select name,english+math+chinese as 总分 from exam_result order by 总分 DESC;
在这里插入图片描述
注意:这里的话是先执行的读取,然后在进行的排序,也就是说重命名工作先进行,再进行的排序,因此在进行排序工作的时候数据库认识 ‘总分’ 就是 english+math+chinese 因此才没有报出未知列的错误!

查询姓孙的同学或者姓曹的同学数学成绩,结果按数学成绩由高到低显示

分析:
需读取的列:
姓名、数学成绩
筛选条件:姓孙或者姓曹
排序:按数学成绩降序排序
SQL语句:
select name,math from exam_result where name like '孙%' or name like '曹%' order by math DESC;
MySQL基本查询_第38张图片

筛选分页结果

语法:
起始下标为0;
select ...from tablename [where...] [order by...] limit n;//从0开始读取n条记录;
select ...from tablename [where...] [order by...] limit s,n;//从s开始读取n条记录;
select ...from tablename [where...] [order by...] limit n offset s;//从s开始读取n条记录;
建议:对未知表进行查询时,最好加一条 LIMIT 1,避免因为表中数据过大,查询全表数据导致数据库卡死;

按 id 降序进行分页,每页 3 条记录,分别显示 第 1、2、3 页

分析:
需要读取的列:
全列;
筛选条件:无
排序:id降序;
每页显示:3条
SQL语句:
第一页:
select * from exam_result order by id DESC limit 0,3;
MySQL基本查询_第39张图片
第二页:
select * from exam_result order by id DESC limit 3,3;
MySQL基本查询_第40张图片
第三页:
select * from exam_result order by id DESC limit 6,3;
MySQL基本查询_第41张图片

update(改)

语法:
UPDATE table_name SET column = expr [, column = expr ...] [WHERE ...] [ORDER BY ...] [LIMIT ...]
使用案例:
MySQL基本查询_第42张图片

将孙悟空同学的数学成绩变更为 80 分

分析:
更新列: 数学成绩;
更新条件: 孙悟空
SQL语句:
update exam_result set math=80 where name='孙悟空';
MySQL基本查询_第43张图片
如果想要完成以上的效果的话,使用以下SQL也是可以的:
insert into exam_result values(2,'孙悟空',87,80,77,null) on duplicate key update math=80;
MySQL基本查询_第44张图片

将曹孟德同学的数学成绩变更为 60 分,语文成绩变更为 70 分

分析:
更新列: 数学、语文;
更新条件: 曹孟德
SQL语句:
update exam_result set math=60,chinese=70 where name ='曹孟德';
MySQL基本查询_第45张图片

将总成绩倒数前三的 3 位同学的数学成绩加上 30 分

分析:
更新列: 数学
更新条件: 总成绩倒数前3
SQL语句:
update exam_result set matn=math+30 order by english +math +chinese ASC limiit 0,3;
MySQL基本查询_第46张图片

将所有同学的语文成绩更新为原来的 2 倍

分析;
更新列: 语文条件
更新条件: 无
SQL语句:
update exam_result set chinese =chinese*2;
MySQL基本查询_第47张图片

delete(删)

语法:
DELETE FROM table_name [WHERE ...] [ORDER BY ...] [LIMIT ...]
测试案例:
MySQL基本查询_第48张图片

删除孙悟空同学的考试成绩

分析:
删除列: 所有列
删除条件: 孙悟空
SQL语句:
delete from exam_result where name='孙悟空';
MySQL基本查询_第49张图片

删除整张表数据

删除列: 所有列
删除条件: 无
SQL语句:
delete from exam_result;
这个语句比较危险,为了后面能够更好的做案例,我们使用一些测试用例来尝试:
MySQL基本查询_第50张图片
在使用delete删除表中所有数据过后,auto_increment的值不会重置:
MySQL基本查询_第51张图片

截断表

语法:
TRUNCATE [TABLE] table_name
这个语句与delete from tablename; 效果类似都是删除表中的所有数据,但是这个删除与与delete删除语句有点不同:

  1. 只能对整表操作,不能对部分数据进行操作,delete可以;
  2. truncate实际上不对数据操作,所以比 DELETE 更快,但是TRUNCATE在删除数据的时候,并不经过真正的事物,所以无法回滚;
  3. 会重置 AUTO_INCREMENT 项
    eg:
    MySQL基本查询_第52张图片

插入查询结果

语法:
INSERT INTO table_name [(column [, column ...])] SELECT ...;
MySQL基本查询_第53张图片

删除表中的的重复复记录,重复的数据只能有一份

分析:
MySQL基本查询_第54张图片

MySQL基本查询_第55张图片

聚合函数

什么是聚合函数?

聚合函数:就是MySQL专门针对一组数据进行统计的内置函数;

MySQL常见聚合函数

聚合函数 功能
count([distinct]) expr 返回某列的行数
sum([distinct] expr) 返回某列的总和,遇到NULL会忽略,不是数字没有意义
avg([distinct] expr) 返回某一列的平均值,不是数字没有意义
max([distinct] expr ) 返回某一列的最大值,不是数字没有意义
min([distinct] expr) 返回某一列的最小值,不是数字没有意义

测试表数据:
MySQL基本查询_第56张图片

统计班级共有多少同学

SQL语句:
select count(*) from exam_result;

MySQL基本查询_第57张图片
使用表达式做统计:
在这里插入图片描述

统计班级收集的 qq 号有多少

SQL语句:
select count(qq) from exam_result;
MySQL基本查询_第58张图片
当count具体统计某一列数据时,如果这一列数据为null时,则不会被统计!

统计本次考试的数学成绩分数个数

SQL语句:
select count(math) from exam_result;

MySQL基本查询_第59张图片

统计本次考试去重过后的数学成绩分数个数

SQL语句:
select count(distinct math) from exam_result;

MySQL基本查询_第60张图片

统计数学成绩总分

SQL语句:
select sum(math) from exam_result;
MySQL基本查询_第61张图片

统计平均总分

SQL语句:
select sum(english+math+chinese ) /count(*) from exam_result;
MySQL基本查询_第62张图片
或者也可以使用avg聚合函数:
SQL语句:
select avg(english+chinese+math) from exam_result;
MySQL基本查询_第63张图片

返回英语最高分

SQL语句:
select max(english) from exam_result;

MySQL基本查询_第64张图片

返回 > 70 分以上的数学最低分

SQL语句:
select min(math) from exam_result where math>70;
MySQL基本查询_第65张图片

group by子句的使用

在select语句中使用group by 子句可以对指定列进行分组查询;
语法:
select .... from tablename [where] group by colname1,colname2...

测试案例

准备工作,创建一个雇员信息表(来自oracle 9i的经典测试表)
emp员工表
dept部门表
salgrade工资等级表

DROP database IF EXISTS `scott`;
CREATE database IF NOT EXISTS `scott` DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci;
 
USE `scott`;
 
DROP TABLE IF EXISTS `dept`;
CREATE TABLE `dept` (
  `deptno` int(2) unsigned zerofill NOT NULL COMMENT '部门编号',
  `dname` varchar(14) DEFAULT NULL COMMENT '部门名称',
  `loc` varchar(13) DEFAULT NULL COMMENT '部门所在地点'
);
 
 
DROP TABLE IF EXISTS `emp`;
CREATE TABLE `emp` (
  `empno` int(6) unsigned zerofill NOT NULL COMMENT '雇员编号',
  `ename` varchar(10) DEFAULT NULL COMMENT '雇员姓名',
  `job` varchar(9) DEFAULT NULL COMMENT '雇员职位',
  `mgr` int(4) unsigned zerofill DEFAULT NULL COMMENT '雇员领导编号',
  `hiredate` datetime DEFAULT NULL COMMENT '雇佣时间',
  `sal` decimal(7,2) DEFAULT NULL COMMENT '工资月薪',
  `comm` decimal(7,2) DEFAULT NULL COMMENT '奖金',
  `deptno` int(2) unsigned zerofill DEFAULT NULL COMMENT '部门编号'
);
 
 
DROP TABLE IF EXISTS `salgrade`;
CREATE TABLE `salgrade` (
  `grade` int(11) DEFAULT NULL COMMENT '等级',
  `losal` int(11) DEFAULT NULL COMMENT '此等级最低工资',
  `hisal` int(11) DEFAULT NULL COMMENT '此等级最高工资'
);
 
 
insert into dept (deptno, dname, loc)
values (10, 'ACCOUNTING', 'NEW YORK');
insert into dept (deptno, dname, loc)
values (20, 'RESEARCH', 'DALLAS');
insert into dept (deptno, dname, loc)
values (30, 'SALES', 'CHICAGO');
insert into dept (deptno, dname, loc)
values (40, 'OPERATIONS', 'BOSTON');
 
insert into emp (empno, ename, job, mgr, hiredate, sal, comm, deptno)
values (7369, 'SMITH', 'CLERK', 7902, '1980-12-17', 800, null, 20);
 
insert into emp (empno, ename, job, mgr, hiredate, sal, comm, deptno)
values (7499, 'ALLEN', 'SALESMAN', 7698, '1981-02-20', 1600, 300, 30);
 
insert into emp (empno, ename, job, mgr, hiredate, sal, comm, deptno)
values (7521, 'WARD', 'SALESMAN', 7698, '1981-02-22', 1250, 500, 30);
 
insert into emp (empno, ename, job, mgr, hiredate, sal, comm, deptno)
values (7566, 'JONES', 'MANAGER', 7839, '1981-04-02', 2975, null, 20);
 
insert into emp (empno, ename, job, mgr, hiredate, sal, comm, deptno)
values (7654, 'MARTIN', 'SALESMAN', 7698, '1981-09-28', 1250, 1400, 30);
 
insert into emp (empno, ename, job, mgr, hiredate, sal, comm, deptno)
values (7698, 'BLAKE', 'MANAGER', 7839, '1981-05-01', 2850, null, 30);
 
insert into emp (empno, ename, job, mgr, hiredate, sal, comm, deptno)
values (7782, 'CLARK', 'MANAGER', 7839, '1981-06-09', 2450, null, 10);
 
insert into emp (empno, ename, job, mgr, hiredate, sal, comm, deptno)
values (7788, 'SCOTT', 'ANALYST', 7566, '1987-04-19', 3000, null, 20);
 
insert into emp (empno, ename, job, mgr, hiredate, sal, comm, deptno)
values (7839, 'KING', 'PRESIDENT', null, '1981-11-17', 5000, null, 10);
 
insert into emp (empno, ename, job, mgr, hiredate, sal, comm, deptno)
values (7844, 'TURNER', 'SALESMAN', 7698,'1981-09-08', 1500, 0, 30);
 
insert into emp (empno, ename, job, mgr, hiredate, sal, comm, deptno)
values (7876, 'ADAMS', 'CLERK', 7788, '1987-05-23', 1100, null, 20);
 
insert into emp (empno, ename, job, mgr, hiredate, sal, comm, deptno)
values (7900, 'JAMES', 'CLERK', 7698, '1981-12-03', 950, null, 30);
 
insert into emp (empno, ename, job, mgr, hiredate, sal, comm, deptno)
values (7902, 'FORD', 'ANALYST', 7566, '1981-12-03', 3000, null, 20);
 
insert into emp (empno, ename, job, mgr, hiredate, sal, comm, deptno)
values (7934, 'MILLER', 'CLERK', 7782, '1982-01-23', 1300, null, 10);
 
insert into salgrade (grade, losal, hisal) values (1, 700, 1200);
insert into salgrade (grade, losal, hisal) values (2, 1201, 1400);
insert into salgrade (grade, losal, hisal) values (3, 1401, 2000);
insert into salgrade (grade, losal, hisal) values (4, 2001, 3000);
insert into salgrade (grade, losal, hisal) values (5, 3001, 9999);

emp员工表

MySQL基本查询_第66张图片
dept部门表
MySQL基本查询_第67张图片
salgrade工资等级表
MySQL基本查询_第68张图片

显示每个部门的平均工资和最高工资

分析:
select avg(sal),max(sal) from emp group by deptno;
MySQL基本查询_第69张图片
如果我们想知道是哪个部分的平均工资和最高工资,我们在读取的时候可以读取工作名;
SQL语句:
select deptno ,avg(sal),max(sal) from emp group by deptno;
MySQL基本查询_第70张图片

显示每个部门的每种岗位的平均工资和最低工资

SQL语句:
select deptno,job ,avg(sal),min(sal) from emp group by deptno,job;
MySQL基本查询_第71张图片

显示平均工资低于2000的部门和它的平均工资

分析:
1、先读取每个部门的平均工资:
SQL语句:
select deptno ,avg(sal) from emp group by deptno;

MySQL基本查询_第72张图片
2、然后从上表的结果中筛选出平均工资低于2000的数据;
SQL语句:
select deptno ,avg(sal) as 平均工资 from emp group by deptno having 平均工资<2000;
在这里插入图片描述
这里我们用到了having子句,having 子句与where子句一样都是起筛选作用的,但是二者却有所不同:

having子句与where子句的区别:

  1. where子句和having子句都是筛选子句具有筛选功能;
  2. where 子句筛选的基本单位是条,having子句的删选基本单位是组;
  3. where子句的执行顺序优先于having子句;
  4. where子句中不可以是用聚合函数,而having子句中可以使用聚合函数
  5. where子句中无法使用select 子句中的别名,而having子句可以;
    这里我们举个例子:
    MySQL基本查询_第73张图片
    我们可以来查询一下,将SCOTT与KING这两个人排除在外的 平均工资低于2000的部门和它的平均工资:
    1、SCOTT与KING排除在外的每个部门的平均工资:
    SQL语句:
    select deptno,avg(sal) as 平均工资 from emp where ename!='SCOTT' and ename!='KING' group by deptno;
    MySQL基本查询_第74张图片
    2、基于上面这个分组查询的结果,我们利用having筛选出符合条件的数据:
    select deptno,avg(sal) as 平均工资 from emp where ename!='SCOTT' and ename!='KING' group by deptno having 平均工资<2000;
    MySQL基本查询_第75张图片
    我们来解析以下上面的SQL语句的执行顺序:

MySQL基本查询_第76张图片

面试题:SQL查询中各个关键字的执行先后顺序 from > on> join > where > group by > with > having > select> distinct > order by > limit
实际上MySQL最大的难点之一就是:select的编码顺序并不是SQL语句的执行顺序,为了编写SQL语句更加流畅,我们可以根据子句的优先级来编写SQL语句,这样有助于我们理解SQL语句的执行逻辑;

关于MySQL的执行顺序,可以参考一下博主的博客:
https://blog.csdn.net/dz77dz/article/details/115111559?spm=1001.2014.3001.5506

你可能感兴趣的:(MySQL,mysql,数据库,c++)