SQL39 筛选昵称规则和试卷规则的作答记录

题目主要信息:

  • 找到昵称以 "牛客"+纯数字+"号" 或者纯数字组成的用户对于字母 c 开头的试卷类别(如C, C++, c#等)的已完成的试卷ID和平均得分
  • 按用户ID、平均分升序排序
  • 分数保留整数

问题拆分:

  • 通过 WITH AS 语句筛选出符合要求的用户和试卷,并存入临时表供接下来使用。知识点:WITH AS, REGEXP, LIKE
    • 用正则表达式判断昵称是否合规,正则表达式中匹配单个纯数字符号为 \d,匹配一个及以上数字为 \d+^ 表示匹配字符串头,$ 表示匹配字符串尾。因此 "牛客"+纯数字+"号" 的判断方式为 REGEXP "^牛客\d+号$",纯数字组成的用户判断方式为 REGEXP "^\d+$"
    • 判断字母 c 开头的试卷类别条件较为简单,可以直接用 SQL 的字符串判断函数 LIKE "c%" 实现
  • 筛选出 exam_record 中 uid 和 exam_id 满足上述条件的数据,对其进行聚合统计。通过 AVG 统计平均分数,并通过 ROUND 保留整数。知识点:AVG, ROUND, GROUP BY
  • 对筛选结果按照 uid 和平均分数排序输出。知识点:ORDER BY

代码:

WITH
valid_u AS (SELECT uid FROM user_info WHERE nick_name REGEXP "^牛客\\d+号$" OR nick_name REGEXP "^\\d+$"),
valid_e AS (SELECT exam_id FROM examination_info WHERE tag LIKE "c%" OR tag LIKE "C%")
SELECT
    uid,
    exam_id,
    ROUND(AVG(score)) AS avg_score
FROM
    exam_record
WHERE
    uid IN (SELECT * FROM valid_u)
    AND exam_id IN (SELECT * FROM valid_e)
    AND score IS NOT NULL
GROUP BY
    uid,
    exam_id
ORDER BY
    uid,
    AVG(score)