【MySQL】把成绩低于总平均成绩的女同学的的成绩提高5%

在MySQL中,

把成绩低于总平均成绩的女同学的的成绩提高5%

#首先我们需要确定[成绩表]里是否存在[外键]

如果不存在,那么我们直接进行update语句即可,

如果存在[外键],我们是没办法进行更改成绩的,

那么我们需要先把这个[成绩表]备份一下,

备份/复制一个表的语法是:

create table 新表名 select * from 旧表名;

相应的如果[成绩表]名为”sc”的话,就随便创建一个新表,表明为”sc1″,那么语法就是:

create table sc1 select * from sc;

备份完[成绩表]之后,

就可以进行更改操作了,

根据题目,首先我们需要确定几个条件,

第一,总平均成绩

第二,成绩低于总平均成绩的人

第三,所有的女生

那么,好,求出平均成绩的语法是:

select avg(成绩) from 表名;

在[成绩表]里,成绩的字段名为:degree,并且需要在刚才的新表中才可以更改,所以就以[sc1]表为例,具体语法:

select avg(degree) from sc1;

第一步到此为止。

接着,成绩低于总平均成绩的人,语法:

where degree < (select avg(degree) from sc1);

第二步到底结束。

接着,所有的女生,有性别的表是[学生表],所以我们要在[学生表]里查询,语法:

select * from student where ssex="女";

但是,我们需要先要想一想,我们查出了所有的女生,但是我们肯定不需要她们所有的信息,只需要其中的一个项(字段)即可,[学生表]和[成绩表]里都有的字段是[学号]”sno”,那么就用[学号]这个字段即可。所以上面的语法要改为:

select sno from student where ssex="女";

那么,好,第三步到此结束。

更新/修改 的语句是:

update 表名 set 列名=表达式... where 条件语句;

所以完整的语句是:

update sc1 set degree=degree*1.05
where sno in (select sno from student where ssex="女")
and degree<(select * from (select avg(degree) as degree from sc1) as a);

好,没了,就这些。

细心的话,会注意到,作为条件的话,一般作为条件的都是一个数据(单个数据),比如[平均成绩]是一个数,比如性别”女”。

但是,

性别为”女”的人的学号是一整列学号,竟然也可以作为条件查询!我还不知道答案的时候,思来想去,不知道如何把一整列学号当作一个条件来使用。

结果一看答案。

惊了!

竟然只用了一个”in”就可以把一整列当作一个条件。

谢谢评论里的提醒,确实是我有地方写错了,这个题我是用Oracle写出来的,我没想到用mysql写出来会出错。

上面的语句已经使用mysql的语法更正。下面说一下会出错的地方有哪些?

两个报错:

报错一:

> 1093 - You can't specify target table 'sc' for update in FROM clause
> 时间: 0.001s

报错翻译是:不能在FROM子句中为UPDATE指定目标表‘sc’。

也就是说,mysql里面,需要update的表和update后面where条件里面的子查询不能是同一个表。(我update的表是sc1,update后面where里面的子查询也是sc1)

这样写会报错:

update sc1 set degree=degree*1.05
where sno in (select sno from student where ssex="女")
and degree<(select avg(degree) as degree from sc1);

那怎么解决呢?只要不是同一个表就行的话,那就把update后面where里面的子查询外面再套一个select。

这样的话,update后面where语句里面的子查询就成了一张临时表。from后面跟一个表名,这一步会让mysql去硬盘里查找是否存在这张表,若存在,我就把这个表的数据形成结果集,拿出来放到内存里,现在我从外面再套一个select from,就是用内存里面的这个结果集里面去查询了,不再是直接从硬盘里去查找了。

报错二:

> 1248 - Every derived table must have its own alias
> 时间: 0s

报错翻译:每个派生表都必须有自己的别名。

也就是说,mysql里面的嵌套子查询需要一个别名。这个报错我在Oracle里面没有见过。现在发现mysql会有这样的问题。

我这样写就会报错:

select * from (select avg(degree) as degree from sc1);

也就是说,外面的这个select from后面的临时表需要一个别名。

如何解决这个报错呢?

解决办法就是,每当遇到一个子查询时,外面的from都加一个别名即可。(别名就是另一个名字,是什么无所谓,只要你理解你知道即可,你给伙伴看的时候一眼就知道啥意思就行,当然了项目中的话,最好别名是有意义的。)

如下:

select * from (select avg(degree) as degree from sc1) as a;

    原文作者:KuYouRan
    原文地址: https://blog.csdn.net/qq_34017390/article/details/109783596
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞