牛客网刷题之SQL篇:非技术快速入门39T

简介: 这篇文章是关于牛客网上的SQL刷题教程,涵盖了基础的SQL运算符和多个实际的数据分析场景,旨在帮助非技术人员快速入门SQL。

前序

SQL 运算符 包括:算术运算符、比较运算符、逻辑运算符、位运算符、

  1. 牛客网刷题之SQL篇:非技术快速入门39T

一、简单的关键字练习 1-10

SQL3-查询结果去重:distinct 关键字
SQL4-查询结果限制返回行数:limit关键字
SQL5-将查询后的列重新命名:as 关键字 or 空格
SQL6-查找学校是北大的学生信息:wherelimit
SQL7 查找年龄大于24岁的用户信息:比较运算符
SQL8 查找某个年龄段的用户信息:比较运算符
SQL10 用where过滤空值练习:is not

二、知识点复习之 运算符

1、算数运算符

中文 运算符
+
-
*
/
求余 %

2、比较运算符

运算符 作用 mybatis语法
= 等于,相等返回值为1,否则返回值为0,1个或2个null返回null,string与int比较则string自动转int
<=> 安全等于,与=的区别是,两个同时为null时返回1,当一个为null,返回值为0
<>(!=) 不等于,相等返回值为0,不相等返回值为1
<= 小于等于,如果小于等于则返回值为1,否则返回值为0 &lt;=
>= 大于等于,如果大于等于则返回值为1,否则返回值为0 &gt;=
> 大于 ,如果大于则返回值为1,否则返回值为0 &gt;
< 小于 ,如果小于则返回值为1,否则返回值为0 &lt;
is null 判断是否为null,如果是null,则返回值为1,否则返回值为0
is not null 判断是否不为null
least 在有两个或多个参数返回最小值
greatest 在有两个或多个参数返回最大值
between and 判断一个值是否落在两个值之间
in 判断一个值在不在列表里
not in 判断一个值不是在列表里
like 通配符匹配,’ % ‘匹配任何数目的字符,’ _ ’ 匹配一个字符
regexp 正则表达式匹配,如果满足则返回1
'^ '匹配以该字符后面的字符开头的字符
’ $ ‘匹配以该字符后面的字符结尾的字符
’ . ‘匹配任何一个字符
’ [0-9 a-z] ’ 匹配0-9 a-z’ * '匹配任何一个字符

3、逻辑运算符

所有逻辑运算符的求值结果均为TRUE(1) FALSE()0 NULL

运算符 作用
not( ! )
and( && )
or ( ||)
xor 异或

4、位运算符

位运算符是在二进制数上进行计算的运算符,位运算符会先将操作数变成二进制数,然后进行位运算,最后将计算结果从二进制变回十进制数
在这里插入图片描述

运算符 作用
| 位或
& 位与
^ 位异或
<< 位左移
>> 位右移
~ 位取反,反转所有比特

三、10-28T

0、简单题总结

SQL14 操作符混合运用:and 和 or 的用法
SQL15 查看学校名称中含北京的用户:like
SQL16 查找GPA最高值:计算函数 max()
SQL17 计算男生人数以及平均GPA:计算函数 count()、avg()

SQL20 分组排序练习题:group、order、avg()
SQL21 浙江大学用户题目回答情况:left join

1. SQL18 分组计算练习题

现在运营想要对每个学校不同性别的用户活跃情况和发帖数量进行分析,请分别计算出每个学校每种性别的用户数、30天内平均活跃天数和平均发帖数量
题目链接

##请分别计算出每个学校每种性别的用户数、30天内平均活跃天数和平均发帖数量。
select
gender,
university,
count(id) as user_num,
avg(active_days_within_30) as avg_active_day,
avg(question_cnt) as avg_question_cnt
from user_profile
group by university,gender

2. SQL19 分组过滤练习题

题目:现在运营想查看每个学校用户的平均发贴和回帖情况,寻找低活跃度学校进行重点运营,请取出平均发贴数低于5的学校或平均回帖数小于20的学校。
题目链接

select
university,
avg(question_cnt) as avg_question_cnt,
avg(answer_cnt) as avg_answer_cnt
from user_profile

group by university
having avg_question_cnt < 5 or avg_answer_cnt <20

3. SQL22 统计每个学校的答过题的用户的平均答题数

运营想要了解每个学校答过题的用户平均答题数量情况,请你取出数据。
题目链接
重点:
每个学校:group by university
用户的平均答题数:count(b.result) / count(distinct b.device_id)
使用left join 还是inner join

select
a.university,
count(b.result) / count(distinct b.device_id) as avg_answer_cnt
from user_profile a
inner join question_practice_detail b on a.device_id = b.device_id
group by a.university
order by a.university

4. SQL23 统计每个学校各难度的用户平均刷题数

题目:运营想要计算一些参加了答题的不同学校、不同难度的用户平均答题量,请你写SQL取出相应数据

select
university, 
difficult_level,
count(b.result) / count(distinct b.device_id) as avg_answer_cnt # 用户平均答题量
from user_profile a
inner join question_practice_detail b on a.device_id = b.device_id
inner join question_detail c on b.question_id = c.question_id
group by university, difficult_level

5、SQL24 统计每个用户的平均刷题数

题目:运营想要查看参加了答题的山东大学的用户在不同难度下的平均答题题目数,请取出相应数据

select
university,
difficult_level,
count(result) / count(distinct b.device_id) as avg_answer_cnt
from user_profile a

left join question_practice_detail b on a.device_id = b.device_id 
left join question_detail c on b.question_id = c.question_id
where university = '山东大学'
group by difficult_level

6、SQL25 查找山东大学或者性别为男生的信息

题目:现在运营想要分别查看学校为山东大学或者性别为男性的用户的device_id、gender、age和gpa数据,请取出相应结果,结果不去重。

select
device_id,
gender,
age,
gpa
from user_profile
where university = '山东大学' 

union all

select
device_id,
gender,
age,
gpa
from user_profile
where gender = 'male'

7、SQL26 计算25岁以上和以下的用户数量

题目:现在运营想要将用户划分为25岁以下和25岁及以上两个年龄段,分别查看这两个年龄段用户数量
本题注意:age为null 也记为 25岁以下

select 
case when age>=25 then '25岁及以上' else '25岁以下' end as age_cut, 
count(device_id) as number
from user_profile
group by age_cut

8、SQL27 查看不同年龄段的用户明细 case_when

题目:现在运营想要将用户划分为20岁以下,20-24岁,25岁及以上三个年龄段,分别查看不同年龄段用户的明细情况,请取出相应数据。(注:若年龄为空请返回其他。)

select
device_id,
gender,
case when age < 20 then "20岁以下"
when age >=20 and age <= 24 then "20-24岁"
when age >=25 then "25岁及以上"
else "其他" end as age_cut
from user_profile

9、SQL28 计算用户8月每天的练题数量

题目:现在运营想要计算出2021年8月每天用户练习题目的数量,请取出相应数据。

select
day(date) as day,
count(question_id) as question_cnt
from question_practice_detail
where month(date)=8 and year(date)=2021
group by day
## 这里 group by date 也可以

--法一:like运算符
select
    day(date) as day,
    count(question_id) as question_cnt
from question_practice_detail
where date like '2021-08%'
group by day(date);

--法二:regexp运算符
select
    day(date) as day,
    count(question_id) as question_cnt
from question_practice_detail
where date regexp '2021-08'
group by day(date);

--法三:substring提取日期
select
    day(date) as day,
    count(question_id) as question_cnt
from question_practice_detail
where substring(date,1,7) = '2021-08'
group by day(date);

函数:
year('2022-12-22') = ‘2022’
month('2022-12-22') \= ‘12’
day('2022-12-22') = ‘22’

四、知识点复习之内外连接

五、知识点复习之union

六、29-39T

  1. SQL29 计算用户的平均次日留存率: *****
  2. SQL30 统计每种性别的人数:substring_index() 字符串函数
  3. SQL31 提取博客URL中的用户名:substring_index() 字符串函数
  4. SQL32 截取出年龄:substring_index() 字符串函数
  5. SQL33 找出每个学校GPA最低的同学
  6. SQL35 浙大不同难度题目的正确率:*****
  7. SQL36 查找后排序:easy order by
  8. SQL37 查找后多列排序:同上
  9. SQL38 查找后降序排列:默认 asc、desc
    10.SQL39 21年8月份练题总数:year(date) = 2021 and month(date) = 8

1、***** SQL29 计算用户的平均次日留存率

描述
题目:现在运营想要查看用户在某天刷题后第二天还会再来刷题的平均概率。请你取出相应数据。

question_practice_detail

id device_id quest_id result date
1 2138 111 wrong 2021-05-03
2 3214 112 wrong 2021-05-09
3 3214 113 wrong 2021-06-15
4 6543 111 right 2021-08-13
5 2315 115 right 2021-08-13
6 2315 116 right 2021-08-14
7 2315 117 wrong 2021-08-15

根据示例,你的查询应返回以下结果:

avg_ret
0.3000
select 
count(date2) / count(date1) as avg_ret
from (
    select
        distinct a.device_id,
        a.date as date1,
        b.date as date2
    from question_practice_detail as a
    left join (
        select distinct device_id, date
        from question_practice_detail
    ) as b
    on a.device_id = b.device_id 
    and date_add(a.date, interval 1 day) = b.date
) as c

##解法2
select avg(if(datediff(date2, date1)=1, 1, 0)) as avg_ret
from (
    select
        distinct device_id,
        date as date1,
        lead(date) over (partition by device_id order by date) as date2
    from (
        select distinct device_id, date
        from question_practice_detail
    ) as uniq_id_date
) as id_last_next_date

问题分解:

  • 限定条件:第二天再来。
    • 解法1:表里的数据可以看作是全部第一天来刷题了的,那么我们需要构造出第二天来了的字段,因此可以考虑用left join把第二天来了的拼起来,限定第二天来了的可以用date_add(date1, interval 1 day)=date2筛选,并用device_id限定是同一个用户。
    • 解法2:用lead函数将同一用户连续两天的记录拼接起来。先按用户分组partition by device_id,再按日期升序排序order by date,再两两拼接(最后一个默认和null拼接),即lead(date) over (partition by device_id order by date)
  • 平均概率:
    • 解法1:可以count(date1)得到左表全部的date记录数作为分母,count(date2)得到右表关联上了的date记录数作为分子,相除即可得到平均概率
    • 解法2:检查date2和date1的日期差是不是为1,是则为1(次日留存了),否则为0(次日未留存),取avg即可得平均概率。

附:lead用法date_add用法, datediff用法, date函数

细节问题:

  • 表头重命名:as
  • 去重:需要按照devece_id,date去重,因为一个人一天可能来多次
  • 子查询必须全部有重命名

2、SQL32 截取出年龄

  1. LOCATE(substr , str ):返回子串 substr 在字符串 str 中第一次出现的位置,如果字符substr在字符串str中不存在,则返回0;

  2. POSITION(substr IN str ):返回子串 substr 在字符串 str 中第一次出现的位置,如果字符substr在字符串str中不存在,与LOCATE函数作用相同;

  3. LEFT(str, length):从左边开始截取str,length是截取的长度;

  4. RIGHT(str, length):从右边开始截取str,length是截取的长度;

  5. SUBSTRING_INDEX(str ,substr ,n):返回字符substr在str中第n次出现位置之前的字符串; substring_index用法

    例子:
    str=www.wikibt.com
    substring_index(str,'.',1)
    结果是:www
    
    substring_index(str,'.',2)
    
    结果是:www.wikibt
    
    如果count是`正数`,那么就是从左往右数,第N个分隔符的左边的所有内容
    如果count是`负数`,那么就是从右往左数,第N个分隔符的右边的所有内容
    
  6. SUBSTRING(str ,n ,m):返回字符串str从第n个字符截取到第m个字符;

  7. REPLACE(str, n, m):将字符串str中的n字符替换成m字符;

  8. LENGTH(str):计算字符串str的长度。

3、SQL33 找出每个学校GPA最低的同学

注意 : inner join. 和 right join 可以,left就不行

select 
a.device_id, 
a.university, 
a.gpa
from user_profile a
inner join
(
    select university, min(gpa) as gpa
    from user_profile
    group by university
) as b
on a.university=b.university and a.gpa=b.gpa
order by a.university

4、SQL34 统计复旦用户8月练题情况

描述
题目: 现在运营想要了解复旦大学的每个用户在8月份练习的总题目数和回答正确的题目数情况,请取出相应明细数据,对于在8月份没有练习过的用户,答题数结果返回0.

示例:用户信息表user_profile
在这里插入图片描述
示例:question_practice_detail
在这里插入图片描述
根据示例,你的查询应返回以下结果:
在这里插入图片描述

select
a.device_id,
'复旦大学' as university,
count(question_id) as question_cnt,
sum(if(b.result = 'right', 1, 0)) as right_question_cnt
from user_profile a

left join question_practice_detail b on a.device_id = b.device_id  and month(date) = 8  ## 注意,month(date) = 8 只能放在这儿

where university = '复旦大学'
group by a.device_id

5、SQL35 浙大不同难度题目的正确率

题目链接
描述

题目:现在运营想要了解浙江大学的用户在不同难度题目下答题的正确率情况,请取出相应数据,并按照准确率升序输出。

示例: user_profile
在这里插入图片描述
示例: question_practice_detail
在这里插入图片描述
示例: question_detail
在这里插入图片描述
根据示例,你的查询应返回以下结果:
在这里插入图片描述

select
difficult_level,
sum(if(b.result = 'right', 1, 0)) / count(result) as correct_rate

from user_profile a
inner join question_practice_detail b on a.device_id = b.device_id
inner join question_detail c on b.question_id = c.question_id
where university = '浙江大学'

group by difficult_level
order by correct_rate asc
相关文章
|
1天前
|
编解码 Java 程序员
写代码还有专业的编程显示器?
写代码已经十个年头了, 一直都是习惯直接用一台Mac电脑写代码 偶尔接一个显示器, 但是可能因为公司配的显示器不怎么样, 还要接转接头 搞得桌面杂乱无章,分辨率也低,感觉屏幕还是Mac自带的看着舒服
|
3天前
|
存储 缓存 关系型数据库
MySQL事务日志-Redo Log工作原理分析
事务的隔离性和原子性分别通过锁和事务日志实现,而持久性则依赖于事务日志中的`Redo Log`。在MySQL中,`Redo Log`确保已提交事务的数据能持久保存,即使系统崩溃也能通过重做日志恢复数据。其工作原理是记录数据在内存中的更改,待事务提交时写入磁盘。此外,`Redo Log`采用简单的物理日志格式和高效的顺序IO,确保快速提交。通过不同的落盘策略,可在性能和安全性之间做出权衡。
1540 5
|
1月前
|
弹性计算 人工智能 架构师
阿里云携手Altair共拓云上工业仿真新机遇
2024年9月12日,「2024 Altair 技术大会杭州站」成功召开,阿里云弹性计算产品运营与生态负责人何川,与Altair中国技术总监赵阳在会上联合发布了最新的“云上CAE一体机”。
阿里云携手Altair共拓云上工业仿真新机遇
|
7天前
|
人工智能 Rust Java
10月更文挑战赛火热启动,坚持热爱坚持创作!
开发者社区10月更文挑战,寻找热爱技术内容创作的你,欢迎来创作!
577 22
|
3天前
|
存储 SQL 关系型数据库
彻底搞懂InnoDB的MVCC多版本并发控制
本文详细介绍了InnoDB存储引擎中的两种并发控制方法:MVCC(多版本并发控制)和LBCC(基于锁的并发控制)。MVCC通过记录版本信息和使用快照读取机制,实现了高并发下的读写操作,而LBCC则通过加锁机制控制并发访问。文章深入探讨了MVCC的工作原理,包括插入、删除、修改流程及查询过程中的快照读取机制。通过多个案例演示了不同隔离级别下MVCC的具体表现,并解释了事务ID的分配和管理方式。最后,对比了四种隔离级别的性能特点,帮助读者理解如何根据具体需求选择合适的隔离级别以优化数据库性能。
201 3
|
10天前
|
JSON 自然语言处理 数据管理
阿里云百炼产品月刊【2024年9月】
阿里云百炼产品月刊【2024年9月】,涵盖本月产品和功能发布、活动,应用实践等内容,帮助您快速了解阿里云百炼产品的最新动态。
阿里云百炼产品月刊【2024年9月】
|
10天前
|
Linux 虚拟化 开发者
一键将CentOs的yum源更换为国内阿里yum源
一键将CentOs的yum源更换为国内阿里yum源
571 5
|
23天前
|
存储 关系型数据库 分布式数据库
GraphRAG:基于PolarDB+通义千问+LangChain的知识图谱+大模型最佳实践
本文介绍了如何使用PolarDB、通义千问和LangChain搭建GraphRAG系统,结合知识图谱和向量检索提升问答质量。通过实例展示了单独使用向量检索和图检索的局限性,并通过图+向量联合搜索增强了问答准确性。PolarDB支持AGE图引擎和pgvector插件,实现图数据和向量数据的统一存储与检索,提升了RAG系统的性能和效果。
|
6天前
|
XML 安全 Java
【Maven】依赖管理,Maven仓库,Maven核心功能
【Maven】依赖管理,Maven仓库,Maven核心功能
233 3
|
9天前
|
存储 人工智能 搜索推荐
数据治理,是时候打破刻板印象了
瓴羊智能数据建设与治理产品Datapin全面升级,可演进扩展的数据架构体系为企业数据治理预留发展空间,推出敏捷版用以解决企业数据量不大但需构建数据的场景问题,基于大模型打造的DataAgent更是为企业用好数据资产提供了便利。
327 2