告别小白!吃透 MySQL 基本查询,看这一篇就够了

🔥海棠蚀omo:个人主页
❄️个人专栏:《初识数据结构》,《C++:从入门到实践》,《Linux:从零基础到实践》,《Linux网络:从不懂到不会》,《MySQL:新手入门指南》
✨追光的人,终会光芒万丈
博主简介:

目录
2.2.3数学成绩是58或者59或者98或者99分的同学及数学成绩
2.2.8孙某同学,否则要求总成绩>200并且语文成绩<数学成绩并且英语成绩>80
2.3.2查询同学各门成绩,依次按数学降序,英语升序,语文升序的方式展示
2.3.4查询姓孙的同学或者姓曹的同学数学成绩,结果按照数学成绩由高到低显示
3.2将曹孟德同学的数学成绩变更为60分,语文成绩变更为70分
前言:
在上一篇文章中,我们讲解了表的约束的相关知识,那么今天这篇文章我们就来详细讲解一下MySQL的基本查询方面的知识,深入探讨一下MySQL是如何通过语句来对数据进行查询的,下面我们一起来看看吧。
其实MySQL的基本查询本质就是对表的增删查改,而对于这部分其实我们在前面的文章中就提京简单介绍过了,不过今天这篇文章我们是来详细讲解这部分的知识。
而表的增删查改我们可以将其分为:Create(创建),Retrieve(读取),Update(更新),Delete(删除)这四个方面。
一.Create
对于create其实就是我们最熟悉的insert语句,对于insert语句我们前面已经见过很多了,并且前面我们所用的语句就是常见的insert语句,所以对于这部分而言,我们知识来补充一下insert语句的其他内容。
1.1替换


那么在上面呢我们创建了一张表,并向表中插入了一些数据,那么下面我们就来试验一下替换的相关语句:


替换我们要用到的关键字就是:replace,用法和insert是一样的,而对于replace有两种情况,就是我们上面展示的两种:
-- 1 row affected; 表示表中没有冲突数据,数据被插入
-- 2 row affected;表示表中有冲突数据吗,删除后重新插入
而上面的第一张图我们想要插入的数据表中是没有的,所以我们就直接插入了数据。而第二张图我们要插入的数据中sn = 20001是与表中的数据冲突的,所以就触发了第二种情况,先把表中冲突的数据给删除,再插入我们的数据。
二.Retrieve
Retrieve其实就是我们常用的select语句,不过我们在前面文章中的使用的select语句是较为简单的,那么下面我们来看一下完整的select语句:

我们平常使用的也就from和where,但其实select语句后面是可以跟多种选项的,那么下面我们就一一来讲解。
2.1SELECT列

那么首先我们来看一些简单的,用select语句来查询表中的列属性,在上面我们先创建一张表,并向表中插入了几组数据。
2.1.1全列查询
对于全列查询我们并不陌生,在前面的文章中我们经常会使用,也就是:

也就是select * from + 表名,通过这个语句我们就能查找出一张表的所有列属性及数据,但是在通常情况下我们不建议使用*进行全列查询,为什么呢?
1.查询的列越多,意味着需要传输的数据量就越大
2.可能会影响到索引的使用
但是如果表中的数据不多,平常练习使用的话还是没有问题的。
2.1.2指定列查询
既然我们可以进行全列查询,那么就可以进行指定列查询,我们来看:

在上面我们就只查询了name这一列的数据,只需要将*替换为你想要查询的列名即可,那么只能够查询这一列的数据吗?当然不是的:

当然是可以同时查询多列数据的,在上面我们就同时查询了name和english这两列的数据。
2.1.3查询字段为表达式
上面我们讲解了查询列的相关语句,而select语句在使用时不仅能写列名,还能够写表达式,什么意思呢?我们来看:



那么对于查询字段为表达式我们将其分为:表达式不包含字段,表达式包含一个字段以及表达式包含多个字段,而上面的三张图我们就演示了这三种情况。
第一种情况没什么好讲的,而剩下的两种情况我们从查询到的数据可以看到得到的结果确实是表达式的结果,不管是英语成绩+10,还是计算三科的总成绩,得到的都是我们所期望的结果。
2.1.4为查询结果指定别名
那么在上面我们得到了三科的总成绩,但是我们看这一列的名字,chinese+math+english这太不优雅了,那么我们要为其换个名字该如何做呢?我们来看:

那么我们的做法就是在相应的字段后面:+ as + 要起的别名,那么从上面的结果可以看到我们就将chinese+math+english这个名字改为了total,比之前优雅多了。

但其实我们在使用的时候也可以选择不加上as,直接在字段的后面加上要起的别名,MySQL是支持这种写法的。
2.1.5结果去重

当我们查询数学成绩的时候,可以看到98分这个成绩重复了,那如果我们想要对数学成绩进行去重该怎么做呢?我们来看:

我们只要加上:distinct关键字即可,从结果可以看到98这个成绩确实已经被去重了。
2.2WHERE条件
那么在上面我们讲完了select语句的基本用法,而select语句后面的可选项我们还没有将,怎么下面我们就来认识一下WHERE条件,那么where都有哪些条件呢?我们一起来看看:
比较运算符:

逻辑运算符:

上面就是我们常用的where条件运算符,where条件所用到的这些运算符就是为了给前半段的select语句在查询的时候加上条件,以便能够得到我们想要的结果。
光看是看不懂的,下面我们直接通过几个例子来带大家更好地去理解这些运算符。
2.2.1英语不及格的同学及英语成绩
对于这个例子我们可以提取出一些信息,分别是:我们要输出姓名和英语成绩,并且输出的英语成绩不及格,即英语成绩<60,那么下面我们就根据这些信息来书写我们的sql语句:

这个比较简单,我们只需要在后面的where语句中加上:english<60即可,从结果中我们也可以看到提取出来的确实是满足上面的条件的。
2.2.2语文成绩在[80,90]分的同学及语文成绩
在这个例子中我们可以提取出的信息是:姓名,语文成绩,语文成绩在[80,90]之间,那么下面我们就来书写我们的sql语句:

那么这里我们就用到了上面的and运算符,and我们就将其理解为:&&即可,比较的规则就不多说了,很简单,从上面可以看到提取出来的结果是没有问题的。
但是这个例子其实不止一种写法,我们再看另一种写法:

在这个语句中我们使用到了上面的between...and...运算符,这个运算符得到的结果也是左闭右闭的,和上面得到的结果是一样的。
2.2.3数学成绩是58或者59或者98或者99分的同学及数学成绩
在这个例子中指定了具体的数学成绩,包括:58,59,98,99分,那么下面我们就来书写我们的sql语句:

对于这种具体指向的查询,我们此时就可以使用or运算符,来对不同的数据进行区分,这里的or我们就可以理解为:||,这样理解在书写sql语句时就更加的从容。
但是这样写重复度高,还有点长,对此我们可以使用另一种写法:

第二种写法我们就用到了in运算符,它的作用和上面我们写的是一样的,不过使用in运算符可以使代码看起来更简洁,更优雅。
2.2.4姓孙的同学及孙某同学
这个有点意思,我们注意区分姓孙的同学和孙某,姓孙表示只要姓氏为孙即可,而孙某不仅姓氏是孙,并且名字还得只有两个字,对于这种例子我们称之为:模糊查询,那么该如何书写我们的sql语句呢?我们来看:

那么对于在这种情况我们就要用到like运算符了,并且针对上面的两种情况,用法也不相同。
我们注意到区分姓孙的同学时我们用的是" % ",而区分孙某时我们用的是" _ ",那么这两者有什么区别呢?
%:匹配任意多个(包括0个)任意字符
_:匹配严格的一个字符
那么通过like运算符我们也成功查询出了想要的数据。
2.2.5语文成绩好于英语成绩的同学
这个例子我们需要的信息:姓名,语文成绩,英语成绩,那么下面我们就来书写我们的sql语句:

这个例子相对简单,只需要在where语句后面加上:chinese>english即可,这个例子中用到运算符我们在前面已经见过了,所以这里就不再赘述。
2.2.6总分在200分以下的同学
这个信息只说了总分在200分以下,但是我们要想得到总分,就得通过三科成绩相加才可以,那么下面我们就来书写一下我们的sql语句:

上面我们就将chinese,math和english三科成绩相加,再通过where语句进行筛选,最后得出了上图所示的结果。
但是我们看上面书写的语句,明显可以看到语句太长了,太不优雅了,并且可能有人就会想到前面我们不是讲了可以给列名起一个别名吗?那么下面我们就来试试:

而当我们给总分起了一个别名total,并用total来进行比较的时候发现报错了,MySQL告诉我们total是一个未知的列名,这是怎么回事呢?
其实这与sql语句的执行顺序有关,什么意思呢?我们来看:

对于sql语句而言,我们既然要查找数据,首先得知道在那张表中查数据,所以先执行from exam_result语句没毛病。
而where语句进行了条件限制,所以我们将where语句的执行放在第二步,将最后的select语句放在了最后,让其根据where的条件去筛选。
那么问题就出来了,我们是在select语句中才起别名的,那么在其之前执行的where语句知道这个别名吗?
很明显不知道,所以就出问题了,那么有什么办法解决这个问题吗?
答案是没有,所以这里我就输出一个结论:别名不能用在where条件语句中!!!
2.2.7语文成绩>80并且不姓孙的同学
看到这个例子我们就该清楚又要使用like运算符了,不过这次有点不一样,那么下面我们就来书写我们的sql语句:

既然是不姓孙的同学,那么我们就要在like运算符前面加上:not,这样才表示不姓孙,剩下的我们在前面都见过,这里就不再赘述了。
2.2.8孙某同学,否则要求总成绩>200并且语文成绩<数学成绩并且英语成绩>80
这个例子相较于前面的会复杂一些,首先是孙某同学,如果不是那么就要满足后面一长串的要求,要求我们都明白了,那么下面我们就来书写一下我们的sql语句:

这个sql稍微长一些,但是逻辑还是比较清晰的,中间需要用到or和and运算符,并且注意后面的一长串需要用括号括起来,最后面是一个整体。
2.3结果排序
有时我们需要查询的数据太多,我们想要对查询到的结果进行排序,该怎么做呢?我们来看:

那么想要对数据进行排序,我们就要用到order by语句,既然要排序,那肯定就会有升序和降序两种形式,那么在MySQL中升序和降序该如何进行表示呢?
-- ASC 为升序(从小到大)
-- DESC 为降序(从大到小)
-- 默认为 ASC,即默认是按照升序进行排列的
光看是没用的,下面我们依旧用几个例子来带大家更好地去理解。
2.3.1同学及数学成绩,数学成绩按升序显示

因为order by默认是升序排序的,所以这里我们直接在order by后面加上:math即可,从上图的结果中我们也可以看到得到的数学成绩确实是按照升序进行排列的。
并且这里我提一点,如果表中有的数据为空,即NULL,那么在排序时NULL视为比任何值都小,也就是升序NULL会出现在最上面,降序的话会出现在最下面!!!
2.3.2查询同学各门成绩,依次按数学降序,英语升序,语文升序的方式展示
这个例子我们看到不仅要求查询各科的成绩,每一科还要按照不同的顺序进行排序,那么下面我们就来书写我们的sql语句:

对于这个例子我们可以看到数学成绩确实是按照降序进行排列的,但是相对应的语文和英语成绩并没有按照升序的方式进行排列,其实对于上面的要求我们一次只能根据一门成绩来进行升序或者降序排列。
因为每个人的三科成绩并不一样,我们如果要想严格按照上面的要求一次性对三科数据进行排序,那么势必会打乱每个人原本的成绩,这样肯定是做不到的。
而MySQL默认会按照第一个要求进行排序,而上面我们写的语句中也就是对数学成绩进行了降序排序。
2.3.3查询同学及总分,由高到低
要求很简单,就是让我们计算总分,并将总分按照降序的方式进行排序,那么下面我们就来书写我们的sql语句:

这个例子的sql语句写起来并不复杂,只要在后面加上:desc,即可完成对从分的降序排序,我们举这个例子的目的不在这里,我们接着往下看:

相信大家看到这个结果可能不太理解,在上面的where语句中我们是不能使用别名的,怎么到order by这里又能使用了呢?
答案还是与语句的执行顺序有关:

这次的顺序与where语句有所不同了,第一步依旧是先找到你要查询的表,这没有问题。
但是第二步的操作就有所变化了,我们要想对数据进行排序的前提是什么?
是不是得有数据啊,所以在order by语句中第二步要执行的是select语句而不是order by语句。
当有了数据后,那么我们就可以对查询到的数据进行排序了,最后第三步的操作就是执行order by语句。
而起别名的操作我们在第二步的时候就已经执行了,那么在执行第三步操作时就不会出现找不到的情况了。
2.3.4查询姓孙的同学或者姓曹的同学数学成绩,结果按照数学成绩由高到低显示
在这个例子中我们就要用到where条件来筛选姓孙的同学和姓曹的同学,再通过order by语句来对数学成绩进行排序,那么下面我们就来书写一下我们的sql语句:

这个sql语句稍微复杂一些,并且通过我们上面的讲解大家要能够清晰地看到该语句的执行顺序:

关于这四步操作我就不再一一介绍了,上面已经介绍过了,上面正是通过这四步操作才得到了我们所看到的结果。
2.4筛选分页结果

这个操作要用到limit关键字,主要就是用来指定的显示表中的部分数据,避免因为表中数据过大而在查询全表数据时导致数据库卡死。
上面就是它的相关用法,下面我们一个一个来演示:

最简单的用法就是在limit后面加上一个数字,表示你要显示几行的数据,就像我们上面演示的:我在limit后面加上了3,也就是显示3行的数据,从结果我们也可以看到确实显示了3行的数据。

而第二种用法就是在后面跟上两个数字,用逗号隔开,这两个数字的含义分别表示:从哪一行开始显示,显示的行数。
第一个数字不是从1开始的,而是从0开始的,和数组下标是一样的,所以我们上面写了2,就会从下标为2的那一行开始显示,也就是从" 猪悟能 "这一行开始。

那么第三种写法需要在两个数字间加上offset,但是这两个数字的含义和上面第二种写法正好相反,也就是第1个数字表示要显示的行数,而第2个数字表示的才是从哪一行开始显示。
并且在实际使用中,我们其实更推荐第三种写法,它比第二种用法更明确。
三.Update
update这个语句就是用来对查询的结果进行列值更新,下面我们就来看一下它的语法:

update语句后面也是可以配合着where,order by等语句来使用的,那么下面我们直接就通过一些例子来带大家更好地去理解。
3.1将孙悟空同学的数学成绩变更为80分

我们先查看一下孙悟空的数学成绩,可以看到当前是78分,那么下面我们就通过update语句来进行修改:


这里我们配合着where语句成功将数学成绩进行了修改。
3.2将曹孟德同学的数学成绩变更为60分,语文成绩变更为70分
这个例子要求比上面多了一点,不过还是一样的思路,下面我们先查看原先的成绩:

那么我们先记下原先的语文和数学成绩,下面我们就通过update语句对其进行修改:

和上面的思路是一样的,无非就是在math后面再加上一个chinese,剩下的没什么区别。
3.3将总成绩倒数前三的3位同学的数学成绩加上30分
这个相较于前面两个复杂了些,我们首先要通过总成绩找出倒数前三的三位同学,并将他们的数学成绩加上30分,那么下我们先不修改,先找出这三位同学:

这里的select语句我们需要结合order by和limit语句结合来使用,通过上面的语句我们也看到了总成绩在倒数前三的三位同学,那么下面我们就将他们的数学成绩加上30分:


那么在上面我们就通过update语句成功将从分后三名的宋公明,刘玄德和曹孟德这三个人的数学成绩加上了30分。
这里要注意:在update语句中不能写成math += 30,MySQL不支持+=这种写法,只支持传统的那种写法。
四.Delete
delete顾名思义就是删除表中的数据,下面我们来看看delete的语法:

delete语句同样也可以和where,order by以及limit语句搭配来使用,下面依旧废话不多说,我们直接通过一些例子来说明。
4.1删除孙悟空同学的考试成绩

那么在删除之前我们先查看一下他的相关信息,那么下面我们就通过delete语句来删除:


那么在上面我们成功将孙悟空的信息从表中删除了。
4.2删除整张表的数据
删除整张表的数据这个操作是相当危险的,不要轻易使用它,下面我们用一个测试表来演示一下:

那么在上面我就创建一张新表,并向里面填入了一些数据,那么下面我们就开始实验:

那么在上面我们就将表中的所有数据给删除了,当我们再次通过select语句来查看时可以看到表中已经没有任何数据了。

但是我们再向表中插入一条数据,可以看到它的id居然不是1而是4,这是怎么回事呢?
在上面我们在创建表的时候id属性设置为自增长,而将表中的数据delete后并不会重置AUTO_INCREMENT项!!!

通过show语句来查看也可以证实这一点,可以看到自增长已经到达5了。
4.3截断表
既然上面的delete无法重置自增长属性,那么该如何做呢?
一种做法就是使用truncate语句来实现,下面我们看一下它的语法:

语法很简单,那么下面我们就来实验一下:



可以看到通过truncate语句我们确实重置了auto_increment项,但是对于truncate我们还要注意下面几点:
1.truncate只能对整表使用,不能像delete一样针对部分数据操作,也就是使用它就会将整张表的数据全部清空。
2.实际上MySQL不对数据操作,所以比delete更快,但是truncate在删除数据的时候,并不经过真正的事务,所以无法回滚。
对于第二点我们后面在讲解事务时在详细说这一点。
五.聚合函数

常见的聚合函数就如上图所示,都是可以帮我们简化书写过程的,那么下面我们就通过一些例子来带大家运用一下这些函数。
5.1统计班级共有多少同学

这里我们依旧使用之前的的那张表,这里我们通过count函数来统计查找到的数据的个数,返回的结果确实是我们表中剩余数据的个数。
5.2统计本次考试的数学成绩分数个数
这个例子和上面的写法是一样的,无非就是将统计的对象换为了数学成绩的个数,那么下面我们就来书写我们的sql语句:

只需要将count函数中的*改为math即可。

但是我们查看数学成绩后,发现有的成绩重复了,那如果我们想要通过count函数查找去重后的成绩个数该怎么做呢?

答案就是我们可以通过distinct来对数学成绩进行去重,不过要注意的是distinct要写在count函数内部,写在外面是会报错的。
5.3统计数学成绩总分
那么这个例子我们就要用到sum函数来进行操作了,下面我们就来书写我们的sql语句:

我们只需要将count函数换成sum函数即可得到所有人数学成绩的总和了。
5.4统计平均总分
那么在这个例子我们要使用的就是avg函数来得到平均分,下面我们就来书写我们的sql语句:

从上图我们通过avg函数就可以得到所有人的平均总分了。
5.5返回英语最高分
那么在这个例子中我们要使用的函数就是max,以此来得到最高分,下面我们就来书写我们的sql语句:


在上面我们就通过max函数拿到了英语成绩的最高分,可以看到90分确实是最高分。
5.6返回 > 70分以上的数学最低分
在这个例子中我们很明显要用到min函数,但是多加了一个条件,是>70分的数学最低分,那么下面就来书写我们的sql语句:

而要想实现这个操作我们要通过where语句的配合来进行,先通过where语句的条件来进行筛选,再在筛选后的结果中找到数学最低分即可。
六.group by子句的使用
在select语句中使用group by字句可以对指定列进行分组查询,下面我们看一下它的语法:

那么对于group by子句,在下面的例子中我们使用oracle 9i的经典测试表来进行演示,共含有三张表,分别是:EMP员工表,DEPT部门表和SALGRADE工资等级表。
那么下面我们就通过一些例子来运用group by语句。
6.1显示每个部门的平均工资和最高工资
在这个例子中很明显,我们首先要做的就是将表按照部门进行分组,在统计每个部分的平均工资和最高工资,那么下面我们就来书写我们的sql语句:

首先我们要先通过group by子句通过deptno部门号进行分组,可以看到总共分为了10,20和30这三个组,之后通过avg和max函数就能够拿到每个部门的平均工资和最高工资了。
6.2显示每个部门的每种岗位的平均工资和最低工资
这个例子相较于上面的例子要求的不仅是每个部门,还要求每种岗位,这相当于我们需要在部门的基础上再次分组,那么下面我们就来书写我们的sql语句:

那么我们要想在部门的基础上再次分组就可以在deptno的后面加上job即可,前面的和上面差不多就不再赘述了。
而通过上面的结果我们也看到了每个部门的每种岗位以及它们的平均工资和最低工资。
6.3显示平均工资低于2000的部分和他的平均工资
对于上面的要求可能大家的第一反应就是要通过where语句拉进行条件筛选,那么按照这个思路我们下面来实验一下:

从上图可以看到当我们使用where语句时就报错了,那既然where语句不能使用,那我们该如何完成上面的操作呢?

答案就是将where换成having即可,where和having它们两个的作用是非常相似的,都是进行条件筛选,但是where是对具体的任意列进行条件筛选,而having是对分组聚合之后的结果进行条件筛选,也就是它们两个的执行顺序是不一样的。
where语句执行的优先级比较高,而having执行的优先级较低,既然知道了having的使用,其实我们也就知道了having一般就是和group by搭配使用的,作用就是对分组进行筛选。
以上就是告别小白!吃透 MySQL 基本查询,看这一篇就够了的全部内容。