Mysql经典入门练习题
<一>分数排名
1.分数排名
题目:
编写一个 SQL 查询student表的分数排名。如果两个分数相同,则两个分数排名(Rank)相同。
例如:
1 | ±—±------+ |
1根据上述给定的 Scores 表,你的查询应该返回(按分数从高到低排列):
请注意,平分后的下一个名次应该是下一个连续的整数值。换句话说,名次之间不应该有“间隔”。
1 | ±------±-----+ |
解题思路:
需要用到的函数:
四大排名函数之一:dense_rank:分组并列连续排名
DENSE_RANK()函数也是排名函数,和RANK()功能相似,也是对字段进行排名,DENSE_RANK()密集的排名他和RANK()区别在于,排名的连续性,DENSE_RANK()排名是连续的,RANK()是跳跃的排名,所以一般情况下用的排名函数就是RANK()。
使用语法:
1 | select dense_rank() over(order by 字段),字段,... |
解答:
1 | select score,dense_rank() over(order by score) as id |
2.实现排名功能,但是排名是非连续的
题目:
排名如下:
1 | ±------±-----+ |
解题思路:
需要用到的函数:
四大排名函数之一:rank:分组并列跳跃排名
RANK()函数,顾名思义排名函数,可以对某一个字段进行排名,这里为什么和ROW_NUMBER()不一样那,ROW_NUMBER()是排序,当存在相同成绩的学生时,ROW_NUMBER()会依次进行排序,他们序号不相同,而Rank()则不一样出现相同的,他们的排名是一样的。
使用语法:
1 | select rank() over(order by 字段),字段,... |
解答:
1 | select score,rank() over(order by score) as id |
扩展:
Sql 四大排名函数(ROW_NUMBER、RANK、DENSE_RANK、NTILE)
row_number:分组连续排名
row_number的用途的非常广泛,一般可以用来实现web程序的分页,他会为查询出来的每一行记录生成一个序号,依次排序且不会重复,注意使用row_number函数时必须要用over子句选择对某一列进行排序才能生成序号。
使用语法:
1 | select row_number() over(order by 字段),字段,... |
NTILE()函数函数的使用
NTILE()函数是将有序分区中的行分发到指定数目的组中,各个组有编号,编号从1开始,就像我们说的’分区’一样 ,分为几个区,一个区会有多少个 。
使用语法
1 | select ntile(*) over(order by 字段),字段,... |
可观看178.分数排名这篇文章。密码178。里面有详细对这四大排名函数的使用。
<二>换座位
题目:
力扣626. 换座位
有一张student座位表,id为学生座位号,其中id 是连续递增的。
现在想改变相邻俩学生的座位,你能不能写一个 SQL来输出想要的结果呢?
1 | 示例: |
假如数据输入的是上表,则输出结果如下:
1 | ±--------±--------+ |
注意:如果学生人数是奇数,则不需要改变最后一个同学的座位。
解题思路:
这里要用到一个函数:
if函数
if函数相当于Java/C++的三元运算符。
IF(expr1,expr2,expr3),如果expr1的值为true,则返回expr2的值,如果expr1的值为false,则返回expr3的值。
使用语法:
1 | select if(i>0,i+1,i-1) as i |
这一题的思路是:
我们使用if函数,如果id为偶数,那就让id-1;否则如果id是奇数让id+1,否者不变(但是我们发现不需要改变最后一个同学的座位,那么,我们还需要一个判断)使用if函数,如果id是奇数并且id不是表中最大(如何知道是最大的呢?当然要用查询max(id))的,那就让id+1,否则就不改变id值。这样即可实现换座位了。换位座位不要忘了排序哦~
那这个代码怎样写呢?
1 | if(id%2=0,id-1,if(id%2=1 and id!=(select max(id) from student),id+1,id) |
解答:
1 | select |
扩展:
IFNULL()函数的使用
IFNULL(expr1,expr2),如果expr1的值为null,则返回expr2的值,如果expr1的值不为null,则返回expr1的值。
NULLIF()函数的使用
NULLIF(expr1,expr2),如果expr1=expr2成立,那么返回值为null,否则返回值为expr1的值。
ISNULL()函数的使用
ISNULL(expr),如果expr的值为null,则返回1,如果expr1的值不为null,则返回0。
<三>关于Date的函数
题目:
现有一份某个网站一天用户登录日志表,如附件。你需要导入Mysql数据库,这里需要的数据是用户ID(id),和时间日志(time)。请写一段SQL语句得到登录人数最高的三个小时人数的平均值。
链接:https://pan.baidu.com/s/1jqiLDMVjhkAWlXMPkeXEhw
提取码:qqnv
解题思路:
分析:
<1>.首先要导入数据表,如果你有navicat直接就可以导入就成。
导入之后你会发现,time是varchar类型的。并不是Date类型的呀!
所以要用到str_to_date ()函数
str_to_date ()函数
1.含义:是将时间格式的字符串(str),按照规定的显示格式(format)转换为DATETIME类型
2.语法: str_to_date(str,format)
3.使用:
1 | SELECT STR_TO_DATE('2020725','%Y%m%d') AS TIME; |
<2>.需要得到登录人数最高的三个小时人数
首先取最高的登录三小时的人数:要用到limit函数
求人数的平均值,那就需要用到count函数咯!并且要使用order by进行倒序排序选出最大的三个。
<3>.把上面的表作为一个临时表来进行取平均值即可
解答:
1 | select avg(num) |

扩展:
1.DATE_FORMAT() 函数:用于以不同的格式显示日期/时间数据。
语法
1 | DATE_FORMAT(date,format) |
date 参数是合法的日期。format 规定日期/时间的输出格式。
可以使用的格式有:(摘自:https://www.w3school.com.cn/sql/func_date_format.asp)
| 格式 | 描述 |
|---|---|
| %a | 缩写星期名 |
| %b | 缩写月名 |
| %c | 月,数值 |
| %D | 带有英文前缀的月中的天 |
| %d | 月的天,数值(00-31) |
| %e | 月的天,数值(0-31) |
| %f | 微秒 |
| %H | 小时 (00-23) |
| %h | 小时 (01-12) |
| %I | 小时 (01-12) |
| %i | 分钟,数值(00-59) |
| %j | 年的天 (001-366) |
| %k | 小时 (0-23) |
| %l | 小时 (1-12) |
| %M | 月名 |
| %m | 月,数值(00-12) |
| %p | AM 或 PM |
| %r | 时间,12-小时(hh:mm:ss AM 或 PM) |
| %S | 秒(00-59) |
| %s | 秒(00-59) |
| %T | 时间, 24-小时 (hh:mm:ss) |
| %U | 周 (00-53) 星期日是一周的第一天 |
| %u | 周 (00-53) 星期一是一周的第一天 |
| %V | 周 (01-53) 星期日是一周的第一天,与 %X 使用 |
| %v | 周 (01-53) 星期一是一周的第一天,与 %x 使用 |
| %W | 星期名 |
| %w | 周的天 (0=星期日, 6=星期六) |
| %X | 年,其中的星期日是周的第一天,4 位,与 %V 使用 |
| %x | 年,其中的星期一是周的第一天,4 位,与 %v 使用 |
| %Y | 年,4 位 |
| %y | 年,2 位 |
2.Limit函数
1.LIMIT子句简介
(原文链接:https://www.yiibai.com/mysql/limit.html )
在SELECT语句中使用LIMIT子句来约束结果集中的行数。LIMIT子句接受一个或两个参数。两个参数的值必须为零或正整数。
下面说明了两个参数的LIMIT子句语法:
1 | SELECT |
我们来查看LIMIT子句参数:
offset参数指定要返回的第一行的偏移量。第一行的偏移量为0,而不是1。count指定要返回的最大行数。
2. 使用MySQL LIMIT获取前N行
可以使用LIMIT子句来选择表中的前N行记录,如下所示:
1 | SELECT |
例如,要查询employees表中前5个客户,请使用以下查询:
1 | SELECT customernumber, customername, creditlimit FROM customers LIMIT 5; |
3. 使用MySQL LIMIT获得最高和最低的值
LIMIT子句经常与ORDER BY子句一起使用。首先,使用ORDER BY子句根据特定条件对结果集进行排序,然后使用LIMIT子句来查找最小或最大值。
注意:
ORDER BY子句按指定字段排序的使用。
4. 使用MySQL LIMIT获得第n个最高值
MySQL中最棘手的问题之一是:如何获得结果集中的第n个最高值,例如查询第二(或第n)贵的产品是哪个,显然不能使用MAX或MIN这样的函数来查询获得。 但是,我们可以使用MySQL LIMIT来解决这样的问题。
- 首先,按照降序对结果集进行排序。
- 第二步,使用
LIMIT子句获得第n贵的产品。
通用查询如下:
1 | SELECT |