sql题目:如何查找重复数据、如何按条件修改数据、查找不在表里的数据
一、如何查找重复数据?
1、题目:编写一个SQL查询,查找学生表中所有重复的学生名。
2、解题思路:
(1)看到“找重复”的关键字眼,首先要用分组函数(group by),再用聚合函数中的计数函数count()给姓名列计数。
(2)分组汇总后,生成了一个字段:姓名 + 计数的临时表。从这个表里选出计数大于1的姓名,就是重复的姓名
3、解题步骤:
(1)第一种:使用子查询
select 姓名 from
(
select 姓名, count(姓名) as 计数
from 学生表
group by 姓名
) as 辅助表
where 计数 > 1;
(2)第二种:这时候有的同学可能会想,为什么要这么麻烦创建一个子查询,不能用这个语句(将count放到where字句中)直接得出答案吗?
select 姓名
from 学生表
group by 姓名
where count(姓名) > 1;
如果我们运行下这个sql语句,会报下面的错误,问题出在哪里呢?
根据 SQL 的执行顺序规则:前面提到聚合函数(count),where字句无法与聚合函数一起使用。因为where子句的运行顺序排在第二,运行到where时,表还没有被分组。如果要对分组查询的结果进行筛选,可以使用having子句。所以,这道题的最优方法如下:
select 姓名
from 学生表
group by 姓名
having count(姓名) > 1;
4、考点
1)考察思路,有两种解题方法,但是使用having语句的方法更高效。
2)考察对having语句的掌握,很多人会把聚合函数写到where子句中。
3)熟记SQL子句的书写顺序和运行顺序。
二、如何按条件修改数据?
1、题目:下图表名是“班级表”,请将班级中所有的1班、2班交换,0班变为3班。要求只使用更新语句(update),不要使用select语句。
2、解题思路:
(1)题目要求按条件更换列中的内容,“条件”我们想到的是sql里的case表达式。
(2)case...when...的使用方法:
(3)更新语句时需要用到update语句,update语句使用方法如下:
update 表名
set 列名 = 修改后的值;
3、解题步骤:
(1)确定case...when...语句中的内容
// 第一个条件是1班换为2班,第二个条件是2班换为1班,最后剩下的0班全部变成3班
// 语句如下:
update 班级表
set 班级 = (case 班级
when 1 then 2
when 2 then 1
else 3
end);
4、本题考点
(1)一般在做SQL面试题时,大部分都是使用select语句完成。但在工作中,也会经常遇到要更新数据的情况。本题考察对update语句的掌握。
(2)考察如何将业务条件用case表达式写出来。
5、举一反三
(1)在遇到需要将表内某列特定值替换成其他值时,记住case表达式如何使用。
(2)本题如果只是要求查询的话,使用select语句即可:
select (上面的case表达式) from 表名
(3)需要直接更新表中的数据的情况,熟记update语句。但要注意,在使用update更新表数据前,最好先将原表备份。
三、查找不在表里的数据
1、题目:下面是学生的名单,表名为“学生表”;近视学生的名单,表名为“近视学生表”。请问不是近视眼的学生都有谁?(“学生表”表中的学号与“近视学生”表中的学生学号一一对应)
2、解题思路
(1)我们先来拆解问题:不是近视眼的学生都有谁?
- “不是近视眼”的学生,近视信息在“近视学生”表里
- “学生都有谁?”,要求的是“学生姓名”,所以我们的输出答案应该是“学生姓名”,这在“学生”表里。
涉及2张以上表的查询时,我们需要用到多表联结。
(2)使用哪种联结呢?我们了解各个联结的情况:
其中上图黑色框里的sql解决的问题是:不在表里的数据,也就是在表A里的数据,但是不在表B里的数据。对于这个题目“不是近视眼的学生都有谁?”,就是在“学生表”里的数据,但是不在“近视学生”表里的数据。我们选择左联结sql语句。
select ...
from 表1 as a
left join 表2 as b
on a.列名=b.列名
where b.列名 is null;
3、考点
(1)本题主要考察多表联结。遇到要查找“不在表里的数据,也就是在表A里的数据,但是不在表B里的数据。”可以使用黑框里的sql语句。
(2)确实容易首先想到 not in 、 not exists ,但是这个 where b.列名 is null 应该更好一些。