返回介绍

文本转换函数

发布于 2024-08-17 15:49:00 字数 9733 浏览 0 评论 0 收藏 0

修复串列了的记录

描述 :现有试卷信息表 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,80 02021-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'
    
  2. 提取字符串中的最后一个部分:
    SELECT SUBSTRING_INDEX('apple,banana,cherry', ',', -1);
    -- 输出结果:'cherry'
    
  3. 提取字符串中的前两个部分:
    SELECT SUBSTRING_INDEX('apple,banana,cherry', ',', 2);
    -- 输出结果:'apple,banana'
    
  4. 提取字符串中的最后两个部分:
    SELECT SUBSTRING_INDEX('apple,banana,cherry', ',', -2);
    -- 输出结果:'banana,cherry'
    

答案

SELECT
    exam_id,
    substring_index( tag, ',', 1 ) tag,
    substring_index( substring_index( tag, ',', 2 ), ',',- 1 ) difficulty,
    substring_index( tag, ',',- 1 ) duration
FROM
    examination_info
WHERE
    difficulty = ''

对过长的昵称截取处理

描述 :现有用户信息表 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牛客 5678901234 号40007算法2020-01-11 10:00:00
61006牛客 67890123456789 号250算法2020-01-02 11:00:00

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

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

uidnick_name
1005牛客 5678901234 号
1006牛客 67890123...

解释:字符数大于 10 的用户有 1005 和 1006,长度分别为 13、17;因此需要对 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 ) > 13 THEN
        CONCAT( SUBSTR( nick_name, 1, 10 ), '...' ) ELSE nick_name
    END AS nick_name
FROM
    user_info
WHERE
    CHAR_LENGTH( nick_name ) > 10
GROUP BY
    uid;

大小写混乱时的筛选统计(较难)

描述

现有试卷信息表 examination_infoexam_id 试卷 ID, tag 试卷类别, difficulty 试卷难度, duration 考试时长, release_time 发布时间):

idexam_idtagdifficultydurationrelease_time
19001算法hard602021-01-01 10:00:00
29002C++hard802021-01-01 10:00:00
39003C++hard802021-01-01 10:00:00
49004sqlmedium702021-01-01 10:00:00
59005C++hard802021-01-01 10:00:00
69006C++hard802021-01-01 10:00:00
79007C++hard802021-01-01 10:00:00
89008SQLmedium702021-01-01 10:00:00
99009SQLmedium702021-01-01 10:00:00
109010SQLmedium702021-01-01 10:00:00

试卷作答信息表 exam_recorduid 用户 ID, exam_id 试卷 ID, start_time 开始作答时间, submit_time 交卷时间, score 得分):

iduidexam_idstart_timesubmit_timescore
1100190012020-01-01 09:01:012020-01-01 09:21:5980
2100290032020-01-20 10:01:012020-01-20 10:10:0181
3100290022020-02-01 12:11:012020-02-01 12:31:0183
4100390022020-03-01 19:01:012020-03-01 19:30:0175
5100490022020-03-01 12:01:012020-03-01 12:11:0160
6100590022020-03-01 12:01:012020-03-01 12:41:0190
7100690012020-05-02 19:01:012020-05-02 19:32:0020
8100790032020-01-02 19:01:012020-01-02 19:40:0189
9100890042020-02-02 12:01:012020-02-02 12:20:0199
10100890012020-02-02 12:01:012020-02-02 12:31:0198
11100990022020-02-02 12:01:012020-01-02 12:43:0181
12101090012020-01-02 12:11:01(NULL)(NULL)
13101090012020-02-02 12:01:012020-01-02 10:31:0189

试卷的类别 tag 可能出现大小写混乱的情况,请先筛选出试卷作答数小于 3 的类别 tag,统计将其转换为大写后对应的原本试卷作答数。

如果转换后 tag 并没有发生变化,不输出该条结果。

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

taganswer_cnt
C++6

解释:被作答过的试卷有 9001、9002、9003、9004,他们的 tag 和被作答次数如下:

exam_idtaganswer_cnt
9001算法4
9002C++6
9003c++2
9004sql2

作答次数小于 3 的 tag 有 c++和 sql,而转为大写后只有 C++本来就有作答数,于是输出 c++转化大写后的作答次数为 6。

思路

首先,这题有点混乱,9004 根据示例数据查出来只有 1 次,这里显示有 2 次。

先看一下大小写转换函数:

1. UPPER(s)UCASE(s) 函数可以将字符串 s 中的字母字符全部转换成大写字母;

2. LOWER(s) 或者 LCASE(s) 函数可以将字符串 s 中的字母字符全部转换成小写字母。

难点在于相同表做连接要查询不同的值

答案

WITH a AS
  (SELECT tag,
          COUNT(start_time) AS answer_cnt
   FROM exam_record er
   JOIN examination_info ei ON er.exam_id = ei.exam_id
   GROUP BY tag)
SELECT a.tag,
       b.answer_cnt
FROM a
INNER JOIN a AS b ON UPPER(a.tag)= b.tag #a 小写 b 大写
AND a.tag != b.tag
WHERE a.answer_cnt < 3;

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文