【SQL】SQL常见面试题总结(4)

目录

  • 1、空值处理
    • 1.1、统计有未完成状态的试卷的未完成数和未完成率
    • 1.2、0 级用户高难度试卷的平均用时和平均得分
  • 2、高级条件语句
    • 2.1、筛选限定昵称成就值活跃日期的用户(较难)
    • 2.2、筛选昵称规则和试卷规则的作答记录(较难)
    • 2.3、各用户等级的不同得分表现占比(较难)
  • 3、限量查询
    • 3.1、注册时间最早的三个人
    • 3.2、注册当天就完成了试卷的名单第三页(较难)
  • 4、文本转换函数
    • 4.1、修复串列了的记录
    • 4.2、对过长的昵称截取处理

1、空值处理

1.1、统计有未完成状态的试卷的未完成数和未完成率

描述:

现有试卷作答记录表 exam_recorduid 用户 ID, exam_id 试卷 ID, start_time 开始作答时间, submit_time 交卷时间,score得分),数据如下:

iduidexam_idstart_timesubmit_timescore
1100190012020-01-02 09:01:012020-01-02 09:21:0180
2100190012021-05-02 10:01:012021-05-02 10:30:0181
3100190012021-09-02 12:01:01(NULL)(NULL)

请统计有未完成状态的试卷的未完成数 incomplete_cnt 和未完成率 incomplete_rate。由示例数据结果输出如下:

exam_idincomplete_cntcomplete_rate
900110.333

解释:试卷 9001 有 3 次被作答的记录,其中两次完成,1 次未完成,因此未完成数为 1,未完成率为 0.333(保留 3 位小数)

思路

这题只需要注意一个是有条件限制,一个是没条件限制的;要么分别查询条件,然后合并;要么直接在 select 里面进行条件判断。

答案

SELECT exam_id,COUNT(submit_time IS NULL OR NULL) incomplete_cnt,ROUND(COUNT(submit_time IS NULL OR NULL)/COUNT(*),3) complete_rate
FROM exam_record
GROUP BY exam_id
HAVING incomplete_cnt <> 0

在这里插入图片描述

注意

  1. COUNT(submit_time IS NULL OR NULL):
  • submit_time IS NULL OR NULL 是一个逻辑表达式。submit_time IS NULL 会返回一个布尔值 TRUEFALSE,然后 OR NULL 操作将结果转换为 TRUENULL。由于 NULLOR 操作中不会影响 TRUE 的结果,所以结果等效于 submit_time IS NULL
  • 这样,表达式的结果是 TRUENULL
  • 然而,COUNT 函数只会计算非 NULL 的值,因此它只会计算 TRUE 的次数。实际上,这意味着它会统计 submit_timeNULL 的次数。
  1. COUNT(submit_time IS NULL):
  • submit_time IS NULL 是一个布尔表达式,会返回 TRUEFALSE
  • 这里 COUNT 函数计算的是真值 TRUEFALSE 的数量,而不是 NULL的数量。
  • 由于 COUNT 只计算非 NULL 的值,这意味着 submit_time IS NULL 返回的所有 TRUEFALSE 值都被计数为 1。因此,它统计的是记录的总数,因为 TRUEFALSE 都不是 NULL

总结

  • 第一个查询 COUNT(submit_time IS NULL OR NULL) 实际上统计的submit_time 列为空的记录数,因为 TRUENULL 中只有 TRUE 被计数。

  • 第二个查询 COUNT(submit_time IS NULL) 统计的是所有记录的总数,因为布尔表达式 TRUEFALSE 都被认为是非 NULL,因此都被计数。

1.2、0 级用户高难度试卷的平均用时和平均得分

描述:

现有用户信息表 user_infouid 用户 ID,nick_name 昵称, achievement 成就值, level 等级, job 职业方向, register_time 注册时间),数据如下:

iduidnick_nameachievementleveljobregister_time
11001机器人 1 号100算法2020-01-01 10:00:00
21002机器人 2 号21006算法2020-01-01 10:00:00

试卷信息表 examination_infoexam_id:试卷 ID, tag:试卷类别, difficulty:试卷难度, duration:考试时长, release_time:发布时间),示例数据如下:

idexam_idtagdifficultydurationrelease_time
19001SQLhard602020-01-01 10:00:00
29002SQLeasy602020-01-01 10:00:00
39004算法medium802020-01-01 10:00:00

试卷作答记录表 exam_recorduid 用户 ID,exam_id 试卷 ID, start_time 开始作答时间, submit_time 交卷时间, score 得分) 示例数据如下:

iduidexam_idstart_timesubmit_timescore
1100190012020-01-02 09:01:012020-01-02 09:21:5980
2100190012021-05-02 10:01:01(NULL)(NULL)
3100190022021-02-02 19:01:012021-02-02 19:30:0187
4100190012021-06-02 19:01:012021-06-02 19:32:0020
5100190022021-09-05 19:01:012021-09-05 19:40:0189
6100190022021-09-01 12:01:01(NULL)(NULL)
7100290022021-05-05 18:01:012021-05-05 18:59:0290

请输出每个 0 级用户所有的高难度试卷考试平均用时和平均得分,未完成的默认试卷最大考试时长和 0 分处理。由示例数据结果输出如下:

uidavg_scoreavg_time_took
10013336.7

解释:0 级用户有 1001,高难度试卷有 9001,1001 作答 9001 的记录有 3 条,分别用时 20 分钟、未完成(试卷时长 60 分钟)、30 分钟(未满 31 分钟),分别得分为 80 分、未完成(0 分处理)、20 分。因此他的平均用时为 110/3=36.7(保留一位小数),平均得分为 33 分(取整)

思路:这题用IF是判断的最方便的,因为涉及到 NULL 值的判断。当然 case when也可以,大同小异。这题的难点就在于空值的处理,其他的这些查询条件什么的,我相信难不倒大家。

SELECT uid,ROUND(AVG(new_score)) AS avg_score,ROUND(AVG(time_diff),1) AS avg_time_tookFROM (SELECT er.uid,IF(er.submit_time IS NOT NULL,TIMESTAMPDIFF(MINUTE,start_time,submit_time),ei.duration) AS time_diff,IF(er.submit_time IS NOT NULL,er.score,0) AS new_scoreFROM exam_record  erLEFT JOIN user_info ui ON er.uid = ui.uidLEFT JOIN examination_info ei ON er.exam_id = ei.exam_idWHERE ui.`level` = 0 AND ei.difficulty = 'hard'
) t
GROUP BY uid

在这里插入图片描述

2、高级条件语句

2.1、筛选限定昵称成就值活跃日期的用户(较难)

描述

现有用户信息表 user_infouid 用户 ID,nick_name 昵称, achievement 成就值, level 等级, job 职业方向, register_time 注册时间),数据如下:

iduidnick_nameachievementleveljobregister_time
11001机器人 1 号10002算法2020-01-01 10:00:00
21002机器人 2 号12003算法2020-01-01 10:00:00
31003高达 3 号22005算法2020-01-01 10:00:00
41004机器人 4 号25006算法2020-01-01 10:00:00
51005机器人 5 号30007C++2020-01-01 10:00:00

现有试卷作答记录表 exam_recorduid 用户 ID,exam_id 试卷 ID, start_time 开始作答时间, submit_time 交卷时间, score 得分) 示例数据如下:

iduidexam_idstart_timesubmit_timescore
1100190012020-01-02 09:01:012020-01-02 09:21:5980
3100190022021-02-02 19:01:012021-02-02 19:30:0187
2100190012021-05-02 10:01:01(NULL)(NULL)
4100190012021-06-02 19:01:012021-06-02 19:32:0020
6100190022021-09-01 12:01:01(NULL)(NULL)
5100190022021-09-05 19:01:012021-09-05 19:40:0189
11100290012020-01-01 12:01:012020-01-01 12:31:0181
12100290022020-02-01 12:01:012020-02-01 12:31:0182
13100290022020-02-02 12:11:012020-02-02 12:31:0183
7100290022021-05-05 18:01:012021-05-05 18:59:0290
16100290012021-09-06 12:01:012021-09-06 12:21:0180
17100290012021-09-06 12:01:01(NULL)(NULL)
18100290012021-09-07 12:01:01(NULL)(NULL)
8100390032021-02-06 12:01:01(NULL)(NULL)
9100390012021-09-07 10:01:012021-09-07 10:31:0189
10100490022021-08-06 12:01:01(NULL)(NULL)
14100590012021-02-01 11:01:012021-02-01 11:31:0184
15100690012021-02-01 11:01:012021-02-01 11:31:0184

题目练习表 practice_recorduid 用户 ID, question_id 题目 ID, submit_time 提交时间, score 得分):

iduidquestion_idsubmit_timescore
1100180012021-08-02 11:41:0160
2100280012021-09-02 19:30:0150
3100280012021-09-02 19:20:0170
4100280022021-09-02 19:38:0170
5100380022021-09-01 19:38:0180

请找到昵称以『机器人』开头『号』结尾、成就值在 1200~2500 之间,且最近一次活跃(答题或作答试卷)在 2021 年 9 月的用户信息。

由示例数据结果输出如下:

uidnick_nameachievement
1002机器人 2 号1200

解释:昵称以『机器人』开头『号』结尾且成就值在 1200~2500 之间的有 1002、1004;

1002 最近一次试卷区活跃为 2021 年 9 月,最近一次题目区活跃为 2021 年 9 月;1004 最近一次试卷区活跃为 2021 年 8 月,题目区未活跃。

因此最终满足条件的只有 1002。

思路

先根据条件列出主要查询语句

昵称以『机器人』开头『号』结尾: nick_name LIKE "机器人%号"

成就值在 1200~2500 之间:achievement BETWEEN 1200 AND 2500

第三个条件因为限定了为 9 月,所以直接写就行:( date_format( record.submit_time, '%Y%m' )= 202109 OR date_format( pr.submit_time, '%Y%m' )= 202109 )

答案:

SELECT DISTINCT u_info.uid,u_info.nick_name,u_info.achievement
FROM user_info u_info
LEFT JOIN exam_record record ON record.uid = u_info.uid
LEFT JOIN practice_record pr ON u_info.uid = pr.uid
WHERE u_info.nick_name LIKE "机器人%号"AND u_info.achievement BETWEEN 1200AND 2500AND (date_format(record.submit_time, '%Y%m')= 202109OR date_format(pr.submit_time, '%Y%m')= 202109)
GROUP BY u_info.uid

2.2、筛选昵称规则和试卷规则的作答记录(较难)

描述

现有用户信息表 user_infouid 用户 ID,nick_name 昵称, achievement 成就值, level 等级, job 职业方向, register_time 注册时间),数据如下:

iduidnick_nameachievementleveljobregister_time
11001机器人1号19002算法2020-01-01 10:00:00
21002机器人2号12003算法2020-01-01 10:00:00
31003机器人3 号 ♂22005算法2020-01-01 10:00:00
41004机器人 4号25006算法2020-01-01 10:00:00
51005机器人555号20007C++2020-01-01 10:00:00
6100666666630006C++2020-01-01 10:00:00

试卷信息表 examination_infoexam_id:试卷 ID, tag:试卷类别, difficulty:试卷难度, duration:考试时长, release_time:发布时间),示例数据如下:

idexam_idtagdifficultydurationrelease_time
19001C++hard602020-01-01 10:00:00
29002c#hard802020-01-01 10:00:00
39003SQLmedium702020-01-01 10:00:00

现有试卷作答记录表 exam_recorduid 用户 ID,exam_id 试卷 ID, start_time 开始作答时间, submit_time 交卷时间, score 得分) 示例数据如下:

iduidexam_idstart_timesubmit_timescore
1100190012020-01-02 09:01:012020-01-02 09:21:5980
2100190012021-05-02 10:01:01(NULL)(NULL)
4100190012021-06-02 19:01:012021-06-02 19:32:0020
3100190022021-02-02 19:01:012021-02-02 19:30:0187
5100190022021-09-05 19:01:012021-09-05 19:40:0189
6100190022021-09-01 12:01:01(NULL)(NULL)
11100290012020-01-01 12:01:012020-01-01 12:31:0181
16100290012021-09-06 12:01:012021-09-06 12:21:0180
17100290012021-09-06 12:01:01(NULL)(NULL)
18100290012021-09-07 12:01:01(NULL)(NULL)
7100290022021-05-05 18:01:012021-05-05 18:59:0290
12100290022020-02-01 12:01:012020-02-01 12:31:0182
13100290022020-02-02 12:11:012020-02-02 12:31:0183
9100390012021-09-07 10:01:012021-09-07 10:31:0189
8100390032021-02-06 12:01:01(NULL)(NULL)
10100490022021-08-06 12:01:01(NULL)(NULL)
14100590012021-02-01 11:01:012021-02-01 11:31:0184
15100690012021-02-01 11:01:012021-09-01 11:31:0184

找到昵称以"机器人"+纯数字+"号"或者纯数字组成的用户对于字母 c 开头的试卷类别(如 C,C++,c#等)的已完成的试卷 ID 和平均得分,按用户 ID、平均分升序排序。由示例数据结果输出如下:

uidexam_idavg_score
1006900184

解释:昵称满足条件的用户有 1001、1002、1004、1005、1006;

c 开头的试卷有 9001、9002;

满足上述条件的作答记录中,1002 完成 9001 的得分有 81、80,平均分为 81(80.5 取整四舍五入得 81);

1002 完成 9002 的得分有 90、82、83,平均分为 85;

思路

还是老样子,既然给出了条件,就先把各个条件先写出来

找到昵称以"机器人"+纯数字+"号"或者纯数字组成的用户: 我最开始是这么写的:nick_name LIKE '机器人%号' OR nick_name REGEXP'^[0-9]+$',如果表中有个 “机器人 H 号” ,那也能通过。

所以这里还得用正则: nick_name LIKE '^机器人[0-9]+号'

对于字母 c 开头的试卷类别: e_info.tag LIKE 'c%' 或者 tag regexp '^c|^C' 第一个也能匹配到大写 C

答案

SELECT UID,exam_id,ROUND(AVG(score), 0) avg_score
FROM exam_record
WHERE UID IN(SELECT UIDFROM user_infoWHERE nick_name RLIKE "^机器人[0-9]+号 $"OR nick_name RLIKE "^[0-9]+$")AND exam_id IN(SELECT exam_idFROM examination_infoWHERE tag RLIKE "^[cC]")AND score IS NOT NULL
GROUP BY UID,exam_id
ORDER BY UID,avg_score;

2.3、各用户等级的不同得分表现占比(较难)

描述

现有用户信息表 user_infouid 用户 ID,nick_name 昵称, achievement 成就值, level 等级, job 职业方向, register_time 注册时间),数据如下:

iduidnick_nameachievementleveljobregister_time
11001机器人1号190算法2020-01-01 10:00:00
21002机器人2号12003算法2020-01-01 10:00:00
31003机器人3 号 ♂220算法2020-01-01 10:00:00
41004机器人 4号250算法2020-01-01 10:00:00
51005机器人555号20007C++2020-01-01 10:00:00
6100666666630006C++2020-01-01 10:00:00

现有试卷作答记录表 exam_recorduid 用户 ID,exam_id 试卷 ID, start_time 开始作答时间, submit_time 交卷时间, score 得分) 示例数据如下:

iduidexam_idstart_timesubmit_timescore
1100190012020-01-02 09:01:012020-01-02 09:21:5980
2100190012021-05-02 10:01:01(NULL)(NULL)
3100190022021-02-02 19:01:012021-02-02 19:30:0175
4100190022021-09-01 12:01:012021-09-01 12:11:0160
5100190032021-09-02 12:01:012021-09-02 12:41:0190
6100190012021-06-02 19:01:012021-06-02 19:32:0020
7100190022021-09-05 19:01:012021-09-05 19:40:0189
8100190042021-09-03 12:01:01(NULL)(NULL)
9100290012020-01-01 12:01:012020-01-01 12:31:0199
10100290032020-02-01 12:01:012020-02-01 12:31:0182
11100290032020-02-02 12:11:012020-02-02 12:41:0176

为了得到用户试卷作答的定性表现,我们将试卷得分按分界点[90,75,60]分为优良中差四个得分等级(分界点划分到左区间),请统计不同用户等级的人在完成过的试卷中各得分等级占比(结果保留 3 位小数),未完成过试卷的用户无需输出,结果按用户等级降序、占比降序排序。

由示例数据结果输出如下:

levelscore_graderatio
30.667
30.333
00.500
00.167
00.167
00.167

解释:完成过试卷的用户有 1001、1002;完成了的试卷对应的用户等级和分数等级如下:

uidexam_idscorelevel score_grade
10019001800
10019002750
10019002600
10019003900
10019001200
10019002890
10029001993
10029003823
10029003763

因此 0 级用户(只有 1001)的各分数等级比例为:优 1/6,良 1/6,中 1/6,差 3/6;3 级用户(只有 1002)各分数等级比例为:优 1/3,良 2/3。结果保留 3 位小数。

思路

先把 将试卷得分按分界点[90,75,60]分为优良中差四个得分等级这个条件写出来,这里可以用到case when

CASEWHEN a.score >= 90 THEN'优'WHEN a.score < 90 AND a.score >= 75 THEN'良'WHEN a.score < 75 AND a.score >= 60 THEN'中' ELSE '差'
END

这题的关键点就在于这,其他剩下的就是条件拼接了

答案

SELECT a.LEVEL,a.score_grade,ROUND(a.cur_count / b.total_num, 3) AS ratio
FROM(SELECT b.LEVEL AS LEVEL,(CASEWHEN a.score >= 90 THEN '优'WHEN a.score < 90AND a.score >= 75 THEN '良'WHEN a.score < 75AND a.score >= 60 THEN '中'ELSE '差'END) AS score_grade,count(1) AS cur_countFROM exam_record aLEFT JOIN user_info b ON a.uid = b.uidWHERE a.submit_time IS NOT NULLGROUP BY b.LEVEL,score_grade) a
LEFT JOIN(SELECT b.LEVEL AS LEVEL,count(b.LEVEL) AS total_numFROM exam_record aLEFT JOIN user_info b ON a.uid = b.uidWHERE a.submit_time IS NOT NULLGROUP BY b.LEVEL) b ON a.LEVEL = b.LEVEL
ORDER BY a.LEVEL DESC,ratio DESC

3、限量查询

3.1、注册时间最早的三个人

描述

现有用户信息表 user_infouid 用户 ID,nick_name 昵称, achievement 成就值, level 等级, job 职业方向, register_time 注册时间),数据如下:

iduidnick_nameachievementleveljobregister_time
11001机器人1号190算法2020-01-01 10:00:00
21002机器人2号12003算法2020-02-01 10:00:00
31003机器人3 号 ♂220算法2020-01-02 10:00:00
41004机器人 4号250算法2020-01-02 11:00:00
51005机器人555号20007C++2020-01-11 10:00:00
6100666666630006C++2020-11-01 10:00:00

请从中找到注册时间最早的 3 个人。由示例数据结果输出如下:

uidnick_nameregister_time
1001机器人1号2020-01-01 10:00:00
1003机器人 3 号 ♂2020-01-02 10:00:00
1004机器人 4 号2020-01-02 11:00:00

解释:按注册时间排序后选取前三名,输出其用户 ID、昵称、注册时间。

答案

SELECT uid,nick_name,register_time
FROM user_info
ORDER BY register_time 
LIMIT 3

在这里插入图片描述

3.2、注册当天就完成了试卷的名单第三页(较难)

现有用户信息表 user_infouid 用户 ID,nick_name 昵称, achievement 成就值, level 等级, job 职业方向, register_time 注册时间),数据如下:

iduidnick_nameachievementleveljobregister_time
11001机器人 1190算法2020-01-01 10:00:00
21002机器人 2 号12003算法2020-01-01 10:00:00
31003机器人 3 号 ♂220算法2020-01-01 10:00:00
41004机器人 4 号250算法2020-01-01 10:00:00
51005机器人 555 号40007算法2020-01-11 10:00:00
61006机器人 6 号250算法2020-01-02 11:00:00
71007机器人 7 号250算法2020-01-02 11:00:00
81008机器人 8 号250算法2020-01-02 11:00:00
91009机器人 9 号250算法2020-01-02 11:00:00
101010机器人 10 号250算法2020-01-02 11:00:00
11101166666630006C++2020-01-02 10:00:00

试卷信息表 examination_infoexam_id:试卷 ID, tag:试卷类别, difficulty:试卷难度, duration:考试时长, release_time:发布时间),示例数据如下:

idexam_idtagdifficultydurationrelease_time
19001算法hard602020-01-01 10:00:00
29002算法hard802020-01-01 10:00:00
39003SQLmedium702020-01-01 10:00:00

现有试卷作答记录表 exam_recorduid 用户 ID,exam_id 试卷 ID, start_time 开始作答时间, submit_time 交卷时间, score 得分) 示例数据如下:

iduidexam_idstart_timesubmit_timescore
1100190012020-01-02 09:01:012020-01-02 09:21:5980
2100290032020-01-20 10:01:012020-01-20 10:10:0181
3100290022020-01-01 12:11:012020-01-01 12:31:0183
4100390022020-01-01 19:01:012020-01-01 19:30:0175
5100490022020-01-01 12:01:012020-01-01 12:11:0160
6100590022020-01-01 12:01:012020-01-01 12:41:0190
7100690012020-01-02 19:01:012020-01-02 19:32:0020
8100790022020-01-02 19:01:012020-01-02 19:40:0189
9100890032020-01-02 12:01:012020-01-02 12:20:0199
10100890012020-01-02 12:01:012020-01-02 12:31:0198
11100990022020-01-02 12:01:012020-01-02 12:31:0182
12101090022020-01-02 12:11:012020-01-02 12:41:0176
13101190012020-01-02 10:01:012020-01-02 10:31:0189

找到求职方向为算法工程师,且注册当天就完成了算法类试卷的人,按参加过的所有考试最高得分排名。排名榜很长,我们将采用分页展示,每页 3 条,现在需要你取出第 3 页(页码从 1 开始)的人的信息。

由示例数据结果输出如下:

uidlevelregister_timemax_score
101002020-01-02 11:00:0076
100302020-01-01 10:00:0075
100402020-01-01 11:00:0060

解释:除了 1011 其他用户的求职方向都为算法工程师;算法类试卷有 9001 和 9002,11 个用户注册当天都完成了算法类试卷;计算他们的所有考试最大分时,只有 1002 和 1008 完成了两次考试,其他人只完成了一场考试,1002 两场考试最高分为 81,1008 最高分为 99。

按最高分排名如下:

uidlevelregister_timemax_score
100802020-01-02 11:00:0099
100572020-01-01 10:00:0090
100702020-01-02 11:00:0089
100232020-01-01 10:00:0083
100902020-01-02 11:00:0082
100102020-01-01 10:00:0080
101002020-01-02 11:00:0076
100302020-01-01 10:00:0075
100402020-01-01 11:00:0060
100602020-01-02 11:00:0020

每页 3 条,第三页也就是第 7~9 条,返回 1010、1003、1004 的行记录即可。

思路

  • 每页三条,即需要取出第三页的人的信息,要用到limit

  • 统计求职方向为算法工程师且注册当天就完成了算法类试卷的人的信息和每次记录的得分,先求满足条件的用户,后用 left join 做连接查找信息和每次记录的得分

答案

SELECT ui.uid,ui.`level`,ui.register_time,MAX(score) AS max_score
FROM exam_record er
INNER JOIN examination_info ei USING(exam_id)
INNER JOIN user_info ui ON er.uid = ui.uid AND DATE(er.submit_time) = DATE(ui.register_time)
WHERE ui.job = '算法'AND ei.tag = '算法'
GROUP BY ui.uid,ui.`level`,ui.register_time
ORDER BY max_score DESC
LIMIT 6,3

4、文本转换函数

4.1、修复串列了的记录

试卷信息表 examination_infoexam_id:试卷 ID, tag:试卷类别, difficulty:试卷难度, duration:考试时长, release_time:发布时间),示例数据如下:

idexam_idtagdifficultydurationrelease_time
19001算法hard602021-01-01 10:00:00
29002算法hard802021-01-01 10:00:00
39003SQLmedium702021-01-01 10:00:00
49004算法,medium,8002021-01-01 10:00:00

录题同学有一次手误将部分记录的试题类别 tag、难度、时长同时录入到了 tag 字段,请帮忙找出这些录错了的记录,并拆分后按正确的列类型输出。

由示例数据结果输出如下:

exam_idtagdifficultyduration
9004算法medium80

思路

先来学习下本题要用到的函数

SUBSTRING_INDEX 函数用于提取字符串中指定分隔符的部分。它接受三个参数:原始字符串、分隔符和指定要返回的部分的数量。

以下是SUBSTRING_INDEX函数的语法:

SUBSTRING_INDEX(str, delimiter, count)
  • str:要进行分割的原始字符串。
  • delimiter:用作分割的字符串或字符。
  • count:指定要返回的部分的数量。
    • 如果 count 大于 0,则返回从左边开始的前 count 个部分(以分隔符为界)。
    • 如果 count 小于 0,则返回从右边开始的前 count 个部分(以分隔符为界),即从右侧向左计数。

下面是一些示例,演示了 SUBSTRING_INDEX 函数的使用:

  1. 提取字符串中的第一个部分:
SELECT SUBSTRING_INDEX('apple,banana,cherry', ',', 1);
-- 输出结果:'apple'
  1. 提取字符串中的最后一个部分:
SELECT SUBSTRING_INDEX('apple,banana,cherry', ',', -1);
-- 输出结果:'cherry'
  1. 提取字符串中的前两个部分:
SELECT SUBSTRING_INDEX('apple,banana,cherry', ',', 2);
-- 输出结果:'apple,banana'
  1. 提取字符串中的最后两个部分:
SELECT SUBSTRING_INDEX('apple,banana,cherry', ',', -2);
-- 输出结果:'banana,cherry'

答案:

SELECTexam_id,substring_index( tag, ',', 1 ) tag,substring_index( substring_index( tag, ',', 2 ), ',',- 1 ) difficulty,substring_index( tag, ',',- 1 ) duration
FROMexamination_info
WHEREdifficulty = ''

在这里插入图片描述

4.2、对过长的昵称截取处理

描述:现有用户信息表 user_infouid 用户 ID,nick_name 昵称, achievement 成就值, level 等级, job 职业方向, register_time 注册时间),数据如下:

iduidnick_nameachievementleveljobregister_time
11001机器人 1190算法2020-01-01 10:00:00
21002机器人 2 号12003算法2020-01-01 10:00:00
31003机器人 3 号 ♂220算法2020-01-01 10:00:00
41004机器人 4 号250算法2020-01-01 11:00:00
51005机器人 567890123 号40007算法2020-01-11 10:00:00
61006机器人 67890123456789 号250算法2020-01-02 11:00:00

有的用户的昵称特别长,在一些展示场景会导致样式混乱,因此需要将特别长的昵称转换一下再输出,请输出字符数大于 10 的用户信息,对于字符数大于 17 的用户输出前 10 个字符然后加上三个点号:『…』。

由示例数据结果输出如下:

uidnick_name
1005机器人 567890123 号
1006机器人 678901234567…

解释:字符数大于 10 的用户有 1005 和 1006,长度分别为 17、22;因此需要对 1006 的昵称截断输出。

思路

这题涉及到字符的计算,要计算字符串的字符数(即字符串的长度),可以使用 LENGTH 函数或 CHAR_LENGTH 函数。这两个函数的区别在于对待多字节字符的方式。

  1. LENGTH 函数:它返回给定字符串的字节数。对于包含多字节字符的字符串,每个字符都会被当作一个字节来计算。
    示例:
SELECT LENGTH('你好'); -- 输出结果:6,因为 '你好' 中的每个汉字每个占3个字节
  1. CHAR_LENGTH 函数:它返回给定字符串的字符数。对于包含多字节字符的字符串,每个字符会被当作一个字符来计算。
    示例:
SELECT CHAR_LENGTH('你好'); -- 输出结果:2,因为 '你好' 中有两个字符,即两个汉字

答案

SELECT uid,(CASE WHEN CHAR_LENGTH( nick_name ) > 17 THENCONCAT(SUBSTR(nick_name,1,17),'...') ELSE nick_nameEND) AS nick_name
FROM user_info
WHERE CHAR_LENGTH(nick_name) > 10

在这里插入图片描述

好文推荐
《【SQL】SQL常见面试题总结(1)》
《【SQL】SQL常见面试题总结(2)》
《【SQL】SQL常见面试题总结(3)》
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/13394.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

SmartEDA助力电工基础实验:打造高效、智能的学习新体验

在电工基础实验的教学与学习中&#xff0c;传统的实验设备往往存在着操作复杂、数据处理繁琐等问题&#xff0c;给学生的学习带来了不小的挑战。然而&#xff0c;随着科技的不断发展&#xff0c;一种名为SmartEDA的智能电工实验辅助设备正逐渐走入课堂&#xff0c;以其高效、智…

Es6-对象新增了哪些扩展?

​&#x1f308;个人主页&#xff1a;前端青山 &#x1f525;系列专栏&#xff1a;Javascript篇 &#x1f516;人终将被年少不可得之物困其一生 依旧青山,本期给大家带来Javascript篇专栏内容:Es6-对象新增了哪些扩展&#xff1f; 目录 一、参数 二、属性 函数的length属性 …

数据结构-栈(带图)

目录 栈的概念 画图理解栈 栈的实现 fun.h fun.c main.c 栈的概念 栈&#xff08;Stack&#xff09;是一种基本的数据结构&#xff0c;其特点是只允许在同一端进行插入和删除操作&#xff0c;这一端被称为栈顶。遵循后进先出&#xff08;Last In, First Out, LIFO&#…

【论文粗读|arXiv】GaSpCT: Gaussian Splatting for Novel CT Projection View Synthesis

Abstract 本文提出了一种新颖的视图合成和3D场景表示方法&#xff0c;用于为计算机断层扫描&#xff08;CT&#xff09;生成新的投影视图。 方法采用了Gaussian Splatting 框架&#xff0c;基于有限的2D图像投影集&#xff0c;无需运动结构&#xff08;SfM&#xff09;方法&am…

Swift 5.9 中 if 与 switch 语句简洁新语法让撸码更带劲

概览 在实际代码开发中&#xff0c;可能初学 Swift 语言的小伙伴们在撸码时最常用的得数 if 和 switch…case 条件选择语句了。不过在某些场景下它们显得略有那么一丢丢“矫揉造作”&#xff0c;还好从 Swift 5.9 开始苹果知趣的为其简化了语法且增强了它们的表现力。 在本篇…

Vitis HLS 学习笔记--优化本地存储器访问瓶颈

目录 1. 简介 2. 代码解析 2.1 原始代码 2.2 优化后 2.3 分析优化措施 3. 总结 1. 简介 在Vitis HLS中&#xff0c;实现II&#xff08;迭代间隔&#xff09; 1是提高循环执行效率的关键。II1意味着每个时钟周期都可以开始一个新的迭代&#xff0c;这是最理想的情况&…

HNCTF ——baby_python

H&NCTF 2024 官方WP (qq.com) OpCodes Pickle.jl (juliahub.com) nc之后 PS D:\ForCode\pythoncode\.idea> nc hnctf.yuanshen.life 33267 # Python 3.10.12 from pickle import loads main b"\x80\x04ctypes\nFunctionType\n(ctypes\nCodeType\n(I1\nI0\nI0\n…

【Vim】

一、什么是Vim&#xff1f; Vim 是一个历史悠久的文本编辑器&#xff0c;可以追溯到 qed。 Bram Moolenaar 于 1991 年发布初始版本。Vim 有着悠久的历史;它起源于 Vi 编辑器&#xff08;1976 年&#xff09;&#xff0c;至今仍在开发中。(Vim has a rich history; it origina…

css+html 爱心❤

效果 代码实现 html <div class"main"><div class"aixin"></div></div>css .main {transform: rotate(-45deg);}.aixin {height: 100px;width: 100px;background-color: red;margin: auto;margin-top: 200px;position: relativ…

MySQL第一次作业(基本操作)

目录 一、登陆数据库 二、创建数据库zoo 三、修改数据库zoo字符集为gbk 四、选择当前数据库为zoo 五、查看创建数据库zoo信息 六、删除数据库zoo 一、登陆数据库 指令&#xff1a; mysql -u root -p 二、创建数据库zoo 指令&#xff1a; create database zoo; 三、修改数…

基于PHP+MySQL组合开发的多用户自定义商城系统源码 附带源代码包以及搭建教程

系统概述 互联网技术的飞速发展&#xff0c;电子商务已成为人们日常生活中不可或缺的一部分。商城系统作为电子商务的核心&#xff0c;其开发技术和用户体验直接影响着电商平台的竞争力和用户满意度。本文旨在介绍一个基于PHPMySQL组合开发的多用户自定义商城系统&#xff0c;…

C++学习~~string类

1.STL简单介绍 &#xff08;1&#xff09;标准模版库&#xff0c;是C里面的标准库的一部分&#xff0c;C标准库里面还有其他的东西&#xff0c;但是我们不经常使用&#xff0c;我们经常使用的还是STL这个标准库部分。 &#xff08;2&#xff09;六大件&#xff1a;仿函数&…

C# WinForm —— 16 MonthCalendar 介绍

1. 简介 可以选择单个日期&#xff0c;也可以选择一段日期&#xff0c;在选择时间范围上 比较适用&#xff0c;但不能跨月份选择日期范围 在直观上&#xff0c;可以快速查看、选择日期/日期范围 2. 常用属性 属性解释(Name)控件ID&#xff0c;在代码里引用的时候会用到,一般…

Uni-app基础知识

uni-app组成和跨端原理 | uni-app官网uni-app,uniCloud,serverless,uni-app组成和跨端原理,基本语言和开发规范,编译器,运行时&#xff08;runtime&#xff09;,逻辑层和渲染层分离https://uniapp.dcloud.net.cn/tutorial/1.adb连接模拟器 找到adb所在位置&#xff08;一般在hb…

C++ 程序员常用的VScode的插件

vscode中好用的插件 Better CommentsBookmarksC/C ThemeChinese (Simplified) (简体中文) Language Pack for Visual Studio CodeclangdClang-FormatCodeLLDBCMakeCMake ToolsCode RunnerCode Spell CheckerCodeSnapColor Highlightvscode-mindmapDraw.io IntegrationError Len…

对称加密算法的应用场景

随着信息技术的飞速发展&#xff0c;数据安全成为了至关重要的议题。在保护数据传输和存储的过程中&#xff0c;加密算法扮演着不可或缺的角色。其中&#xff0c;对称加密算法&#xff0c;由于其高效性和易用性&#xff0c;被广泛应用于各种场景中。本文将探讨对称加密算法的主…

Kubernets多master集群构建负载均衡

前言 在构建 Kubernetes 多 Master 集群时&#xff0c;实现负载均衡是至关重要的一环。通过多台 Master 节点配合使用 Nginx 和 Keepalived 等工具&#xff0c;可以有效提高集群的可靠性和稳定性&#xff0c;确保系统能够高效运行并有效应对故障。接下来将介绍如何配置这些组件…

物业水电抄表系统的全面解析

1.系统概述 物业水电抄表系统是现代物业管理中的重要组成部分&#xff0c;它通过自动化的方式&#xff0c;实时监控和记录居民或企业的水电使用情况&#xff0c;极大地提高了工作效率&#xff0c;降低了人工抄表的错误率。该系统通常包括数据采集、数据传输、数据分析和数据展…

链表OJ题(移除链表元素,反转链表,分割链表,环形链表(是否成环问题),链表中间节点(快慢指针讲解),环形链表(找入环节点))“题目来源力扣附带题目链接”

目录 1.移除链表元素 2.反转链表 2.1三指针法 2.2头插法 3.分割链表 4.链表的中间节点&#xff08;快慢指针&#xff09; 4.1快慢指针 4.2求链表的中间节点 5.环形链表 5.1环形链表是否成环 5.2环形链表入环节点 5.3入环节点推论的不完备性说明 1.移除链表元素 移除…

Microsoft Threat Modeling Tool 使用(三)

Boundary&#xff08;边界&#xff09; 本文介绍信任边界&#xff0c;基于 SDL TM Knowledge Base (Core) 模版&#xff0c;这是一个通用的威胁建模模板&#xff0c;非常适合初学者和大多数威胁建模需求。 这些边界&#xff08;Boundary&#xff09;在微软威胁建模工具中用于表…