牛客网在线编程SQL篇非技术快速入门题解(二)
大家好,我是RecordLiu。
初学SQL,有哪些合适的练习网站推荐呢?
如果你有编程基础,那么我推荐你到Leetcode这样的专业算法刷题网站,如果没有,也不要紧,你也可以到像牛客网一样的编程网站去练习。
牛客网有很多面向非技术人员的练习题目,很适合入门。
今天给大家分享的是牛客网在线编程SQL篇非技术快速入门题解第二弹。
题目直达链接:
牛客网非技术快速入门SQL编程练习题目
切换到SQL篇就能看到了。

我这里先列一下题目分类:

接下来,我们来详细看一看。
多表查询-子查询
1.现在运营想要查看所有来自浙江大学的用户题目回答明细情况,请你取出相应数据。用户信息保存在user_profile中,用户答题信息保存在question_practice_detail中。
示例:user_profile

示例:question_practice_detail

返回结果

题解
题目要求查出的是浙江大学的用户答题明细,因此需要同时用到用户信息表和答题信息表两张表。
第一种方式是使用内连接方式来解这道题。通过设备号(device_id)将两张表关联起来,再把学校为浙江大学的用户答题信息过滤出来。
SQL中的连接操作可以把多张表的字段水平连接起来,相当于组成一张大的宽表返回。
内连接使用inner join实现。
连接可以理解成是表的横向拓展,这样就可以使用另一张表(或更多表)里面的字段了。
那怎样在不使用表连接的方式下,用到其他表里面的字段呢?SQL中可以用子查询来实现。
子查询又称为嵌套查询。子查询允许我们将一张表的查询结果作为另一张表的过滤条件的数据输入。
怎么理解呢,我举个例子可能会明白些:
# 子查询例子,作为in的过滤条件
SELECT f1,f2
FROM t1
WHERE f1 IN(
SELECT f1 FROM t2 WHERE f3=xxx
);
这道题中,我们可以先从用户表中过滤出是浙江大学的记录,记为一个子查询,这个查询结果只保留是浙江大学的设备ID列表,假设把这个临时结果记为u_p。
然后再查询答题信息表,再根据子查询结果u_p的保存设备列表去过滤出符合条件的设备号和答题信息,也可以解此道题。
代码参考
方法1:内连接实现
SELECT qpd.device_id,
qpd.question_id,qpd.result
FROM question_practice_detail AS qpd
INNER JOIN user_profile AS up
ON qpd.device_id =up.device_id
AND up.university = '浙江大学';
方法2:子查询实现
SELECT device_id,question_id,result
FROM question_practice_detail
WHERE device_id IN(
SELECT device_id FROM user_profile WHERE university='浙江大学'
)
多表查询-链接查询
2.运营想要了解每个学校答过题的用户平均答题数量情况,请你取出数据。其中,用户信息保存在表user_profile中,用户的答题信息保存在question_practice_detail中。设备号可以唯一标识一个用户。
说明
某学校用户平均答题数量计算方式为该学校用户答题总次数除以答过题的不同用户个数,需要对结果保留4位小数,结果按照university升序排序:
示例:user_profile

示例:question_practice_detail

返回结果

题解
题目要求计算的是用户的平均答题次数,计算公式为答题次数/答题用户数。
答题次数可以从用户的答题信息表统计出来,使用count函数,对列question_id计算总和即可。
答题的用户数也是从用户的答题信息表统计出来,也是使用count函数,对列device_id进行计算总和。但题目要求是不同的用户数,所以需要结合去重函数distinct对设备号进行去重。
由于需要按不同学校进行统计,所以需要内联表用户信息,通过设备号把两张表里面的数据关联起来,再按university字段进行分组。
还有一点,题目要求对结果保留4位小数,我们可以使用round函数对结果进行四舍五入并且保留4位小数。
最后,需要使用order by对university字段进行升序排列。
代码参考
SELECT up.university,ROUND(COUNT(qpd.question_id) / COUNT(DISTINCT qpd.device_id),4)
FROM question_practice_detail AS qpd
INNER JOIN user_profile AS up
ON qpd.device_id = up.device_id
GROUP BY up.university
ORDER BY up.university ASC;
多表查询-组合查询
3.现在运营想要分别查看学校为山东大学或者性别为男性的用户的device_id、gender、age和gpa数据,请取出相应结果,结果不去重。
示例:user_profile

返回结果

题解
题目要求是查出山东大学或者性别为男性的用户信息,并且结果不去重。
那过滤条件可不可以直接写成where university=‘山东大学’ or gender='male’呢?
我们注意看示例中这条记录:

这条记录同时满足学校为山东大学以及性别为男性,如果使用上述的过滤条件,查询出来的结果将会只有一条,但题目要求返回的是两条,我们看示例返回的结果就清楚了。
这道题本质是考察union的用法。
join可以理解成是表之间的水平连接操作,而union则是表之间的垂直连接操作。
union允许我们将多个select查询结果组合在一起。
但使用前提是每个select查询需要满足查询的结构一致,即查询的列名相同、查询的列顺序保持一致。
其中,union默认会将查询出的结果进行去重,union all不对结果进行去重,将会返回所有组合在一起的结果。
回到这道题中,可以将查询出学校为山东大学和查询出性别为男性的结果使用union all操作组合在一起。
这样就可以把同时满足学校为山东大学且性别为男性的记录查询出两条了。
代码参考
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'
必会的常用函数-条件函数
4.现在运营想要将用户划分为25岁以下和25岁及以上两个年龄段,分别查看这两个年龄段用户数量。其中,age为null 也记为25岁以下
示例:user_profile

返回结果

题解
这道题很多解法,我这里主要给大家讲一下用case函数来实现。
返回结果中age_cut这列在用户信息表是没有的,所以我们需要利用条件函数来生成age_cut这个辅助列。
那具体如何生成辅助列呢?看完case函数的用法你就知道了。
接下来,我给你详细说说。
case函数是一种多分支的条件表达式,它是用来匹配多种情况的。
case函数基本语法如下
简单case函数
基本语法:
CASE 测试表达式
WHEN 简单表达式1 THEN 结果表达式1
WHEN 简单表达式2 THEN 结果表达式2 ...
WHEN 简单表达式n THEN 结果表达式n
[ELSE 结果表达式n+1 ]
END
简单case的执行顺序,先计算测试表达式的值,然后将计算出的结果从上到下依次和when后面的简单表达式进行对比,其中有一个匹配就终止case语句。
如果都没有匹配上,在书写了else语句情况下,会使用默认的结果表达式,否则会返回NULL。
举例
比如有个发货订单表(order),表里面有个订单状态字段(status),取值分别为0、1、2,对应未发货、已发货、已收到三种状态。
现在要求你对查出的订单状态字段用中文进行命名。
使用简单case函数实现如下:
SELECT
CASE status
WHEN 0 THEN '未发货'
WHEN 1 THEN '已发货'
WHEN 2 THEN '已收到'
END AS 订单状态
FROM order
搜索case函数
基本语法:
CASE
WHEN 布尔表达式1 THEN 结果表达式1
WHEN 布尔表达式2 THEN 结果表达式2 ...
WHEN 布尔表达式n THEN 结果表达式n
[ELSE 结果表达式n+1 ]
END
与简单case函数不同的是,搜索case函数不需要带测试表达式,而是从上到下,依次比较when后面的布尔表达式,如果其中一个为真,就执行then后面的结果表达式,并停止往下匹配。
如果没有一个布尔表达式满足,在书写了else语句情况下,会使用默认的结果表达式,否则会返回NULL。
举例
假设用户信息表user中有一个年龄字段age,记录的是用户的周岁,比如20、25、30等。
现在需要你对用户年龄进行分段,划分为0-17岁、18-25岁、26-35岁、36-45岁、46-55岁、56岁及以上。
使用搜索case实现如下:
SELECT
CASE
WHEN age >=0 AND age <= 17 THEN "0-17岁"
WHEN age >= 18 AND age <= 25 THEN "18-25岁"
WHEN age >= 26 AND age <= 35 THEN "26-35岁"
WHEN age >= 36 AND age <=45 THEN "36-45岁"
WHEN age >= 46 AND age <= 55 THEN "46-55岁"
ELSE "56岁及以上"
END
FROM user
代码参考
使用case实现这道题
SELECT CASE
WHEN age < 25 OR age is NULL THEN '25岁以下'
WHEN age >=25 THEN '25岁及以上'
END AS age_cut,COUNT(*) AS number
FROM user_profile
GROUP BY age_cut
这道题中,我们通过case函数给每条记录生成了一个辅助列age_cut,这个辅助列只有两个取值,分别为25岁以下和25岁及以上,再对列进行分组后,就可以统计出两个类型的用户数量了。
作为拓宽思路,我给你列举了一些其他的解题思路,大家可以看看。
使用if实现
SELECT IF(age<25 OR age IS NULL,'25岁以下','25岁及以上') age_cut,COUNT(device_id) Number
FROM user_profile
GROUP BY age_cut
使用union实现
SELECT '25岁以下' AS age_cut,COUNT(device_id) number
FROM user_profile
WHERE age<25 OR age IS NULL
UNION
SELECT '25岁及以上' AS age_cut,COUNT(device_id) number
FROM user_profile
WHERE age>=25
GROUP BY age_cut
使用子查询实现
SELECT age_cut,COUNT(device_id) AS number FROM
(SELECT IF(age>=25,'25岁及以上','25岁以下') age_cut,device_id
FROM user_profile) u2
GROUP BY age_cut;
必会的常用函数-时间函数
5.现在运营想要计算出2021年8月每天用户练习题目的数量,请取出相应数据。
示例

返回结果

题解
这道题中,我们需要对date字段进行分组后,再统计每个日期的答题数量。
题目的限定条件为2021年8月份的数据,有多种过滤方式,你可以直接用date >= '2021-08-01' AND date <= '2021-08-31'进行判断,或者使用date_format函数,写成DATE_FORMAT(date,'%Y%m') = 202108。
在结果中,我们只需要返回日期中天数,因此需要使用day函数取date字段中的天数,再进行别名处理。
代码参考
SELECT day(date) as day,COUNT(question_id) question_cnt
FROM question_practice_detail
WHERE DATE_FORMAT(date,'%Y%m') = 202108
GROUP BY date;
在这里,我给你总结了常用的日期函数的用法:
返回日期中的年份
year('2021-08-01')返回结果:2021
返回日期中的月份
month('2021-08-01')返回结果:8
返回日期中的天数
day('2021-08-01') 返回结果:1
日期格式化
DATE_FORMAT('2021-08-01 12:30:00','%Y%m%d')返回结果:20210801
日期增加1天
date_add('2021-08-01 12:30:00',interval 1 day), 返回结果:2021-08-02 12:30:00
返回两个日期之间的天数datediff('2021-08-31','2021-08-30')返回结果:1
必会的常用函数-文本函数
6.现在运营想要计算出2021年8月每天用户练习题目的数量,请取出相应数据。
示例:

返回结果

题解
这道题中,我们需要统计每种性别对应人数,但从示例中可以看出,没有单独的性别字段,无法直接统计。
用户的性别信息保存在profile字段中,因此我们需要从profile字段中截取出性别信息为每条记录生成一个辅助列gender,再按gender分组后,统计出总数量。
sql中的字符串截取可以使用substring_index函数来实现,具体用法:substring_index(字符串,分割符,取多少位)。
比如有一个字符串为‘a,b,c,d’
截取字符a
substring_index(‘a,b,c,d’,',',1)
截取字符a,b
substring_index(‘a,b,c,d’,',',2)
截取字符串b
substring_index(substring_index(‘a,b,c,d’,',',2),',',-1)
截取字符d
substring_index(‘a,b,c,d’,',',-1)
截取字符c,d
substring_index(‘a,b,c,d’,',',-1)
截取字符c
substring_index(substring_index(‘a,b,c,d’,',',-2),',',1)
从以上例子可以看出,当substring_index第三个参数为正数时,表示从左到右取n个子串;为负数时,则刚好相反,表示从右到左取n个子串。
代码参考
SELECT SUBSTRING_INDEX(profile,',',-1) as gender,
COUNT(device_id) AS number
FROM user_submit
GROUP BY gender
必会的常用函数-窗口函数
7.现在运营想要找到每个学校gpa最低的同学来做调研,请你取出每个学校的最低gpa。
示例:

返回结果

题解
这道题中,我们能不能直接按学校分组后,取出最低的gpa呢,sql实现如下:
SELECT device_id,university,min(gpa) FROM user_profile GROUP BY university ORDER BY university ASC;
提交之后,你会发现结果并不正确,为什么呢?大家可以思考下原因。
这道题我们可以利用SQL中的窗口函数来实现,在窗口函数里,按university字段进行分区后,再对gpa字段进行升序排列,再通过row_number()函数为每条记录生成一个辅助的排名字段,每个分区里面的第一名就是我们所要求的值。
代码参考
SELECT device_id,university,gpa FROM (
SELECT *,
row_number() OVER (PARTITION BY university ORDER BY gpa ASC) AS u_rank
FROM user_profile) AS u_p
WHERE u_p.u_rank = 1
ORDER BY university ASC;
好了,今天的文章就分享到这里了,如果觉得我的文章对你有帮助,欢迎多分享给你身边的朋友。
相关文章:
牛客网在线编程SQL篇非技术快速入门题解(二)
大家好,我是RecordLiu。 初学SQL,有哪些合适的练习网站推荐呢? 如果你有编程基础,那么我推荐你到Leetcode这样的专业算法刷题网站,如果没有,也不要紧,你也可以到像牛客网一样的编程网站去练习。 牛客网有很多面向非技…...
航天器轨道六要素和TLE两行轨道数据格式
航天器轨道要素 椭圆轨道六根数指的是:半长轴aaa,离心率e,轨道倾角iii、升交点赤经Ω\OmegaΩ、近地点辐角ω\omegaω、和过近地点时刻t0t_0t0(或真近点角φ)。 决定轨道形状: 轨道半长轴aaa࿱…...
【Spring Cloud Alibaba】第01节 - 课程介绍
一、Spring Cloud Alibaba 阿里巴巴公司 以Spring Cloud的衍生微服务一站式解决方案 二、学习Spring Cloud Alibaba的原因 Spring Cloud 多项组件宣布闭源或停止维护Spring Cloud Alibaba 性能优于Spring Cloud 三、适应群体 有Java编程和SpringBoot基础,最好有Sp…...
iOS和Android手机浏览器链接打开app store或应用市场下载软件讲解
引言当开发一个app出来后,通过分享引流用户去打开/下载该app软件,不同手机下载的地方不一样,比如:ios需要到苹果商店去下载,Android手机需要到各个不同的应用商店去下载(华为手机需要到华为应用商店下载,vi…...
2023第十四届蓝桥杯省赛java B组
试题 A: 阶乘求和 本题总分:5 分 【问题描述】 令 S 1! 2! 3! ... 202320232023!,求 S 的末尾 9 位数字。 提示:答案首位不为 0。 【答案提交】 这是一道结果填空的题,你只需要算出结果后提交即可。本题的结果为一 个整数…...
windows下如何快速搜索文件内容
安装git,使用linux命令 grep 这里不再多说 windows版本的命令 Windows提供find/findstr类似命令,其中findstr要比find功能更多一些,可以/?查看帮助。...
Redis集群分片
文章目录1、Redis集群的基本概念2、浅析集群算法-分片-槽位slot2.1 Redis集群的槽位slot2.2 Redis集群的分片2.3 两大优势2.4 如何进行slot槽位映射2.5 为什么redis集群的最大槽数是16384个?2.6 Redis集群不保证强一致性3、集群环境搭建3.1 主从容错切换迁移3.2 主从…...
ISP-AF相关-聚焦区域选择-清晰度评价-1(待补充)
1、镜头相关 镜头类型 变焦类型: 定焦、手动变焦、自动变焦 光圈: 固定光圈、手动光圈、自动光圈 视场角: 鱼眼镜头、超广角镜头、广角镜头、标准镜头、长焦镜头、超长焦镜头(由大至小) 光圈: 超星…...
[element-ui] el-table行添加阴影悬浮效果
问题: 在el-table每一行获得焦点与鼠标经过时,显示一个整行的阴影悬浮效果 /*其中,table-row-checkd是我自定义的焦点行添加类名,大家可以自己起名*/ .el-table tbody tr:hover,.el-table tbody tr.table-row-checked{box-shadow: 0px 3px …...
分布式存储技术(上):HDFS 与 Ceph的架构原理、特性、优缺点解析
面对企业级数据量,单机容量太小,无法存储海量的数据,这时候就需要用到多台机器存储,并统一管理分布在集群上的文件,这样就形成了分布式文件系统。HDFS是Hadoop下的分布式文件系统技术,Ceph是能处理海量非结…...
【python设计模式】20、解释器模式
哲学思想: 解释器模式(Interpreter Pattern)是一种行为型设计模式,它提供了一种方式来解释和执行特定语言的语法或表达式。该模式中,解释器通过将表达式转换为可以执行的对象来实现对表达式的解释和执行。通常…...
【PostgreSQL】通过docker的方式运行部署PostgreSQL与go操作数据库
目录 1、docker的方式运行部署PostgreSQL 2、控制台命令 3、go操作增删改查 1、docker的方式运行部署PostgreSQL docker pull postgres docker run --name learn_postgres -e POSTGRES_PASSWORDdocker_user -e POSTGRES_USERdocker_user -p 5433:5432 -d postgres进入容器&am…...
Kotlin协程序列:
1: 使用方式一 ,callback和coroutine相互转化。 import kotlinx.coroutines.* import java.lang.Exception class MyCallback {fun doSomething(callback: (String?, Exception?) -> Unit) {// 模拟异步操作GlobalScope.launch {try {delay(1000) // 延迟 1 秒…...
java获取视频时长
1、先导包 <dependency><groupId>ws.schild</groupId><artifactId>jave-all-deps</artifactId><version>2.6.0</version> </dependency>2、获取时长 Testpublic void test01() {long time 0;try {String url "http://…...
EDAS投稿系统的遇到的问题及解决办法
问题1: gutter: Upload failed: The gutter between columns is 0.2 inches wide (on page 1), but should be at least 0.2 inches 解决: 在\begin{document}前添加\columnsep 0.201 in(0.2in也会报错,建议填大一点点)…...
t-learning 产品经理课程笔记
t-learning 腾讯公开课——产品经理课程 第一课 化身用户研究员,张小龙《产品精讲》 1-3:执行 4-7:中坚力量 7:核心leader 能解决问题的,就是好的产品经理 如何储备产品知识与素养 (1)了解并…...
校招,从准备开始准备(持续更新ing...)
诸神缄默不语-个人CSDN博文目录 作者现在有科研任务在身(今天还在标数据哦),所以不能实习。 所以就是纯纯拉个表。 最近更新时间:2023.4.9 最早更新时间:2023.4.6 文章目录1. 学习资料和知识点清单1.1 机器学习1.2 深…...
Android:使用LayerDrawable动态生成四宫格头像(包含双人、三人头像)
其实用自定义View也可以实现,我比较懒,就用LayerDrawable来创建一个新的Drawable资源实现。 举例4宫格,9宫格原理类似,每个图标的位置需要用边距慢慢调成预期的效果 效果如下: 双人头像: 三人头像&#x…...
Android Jetpack 从使用到源码深耕【数据库注解Room 从实践到原理 】(三)
前面两篇文章,我们一起学习了,Room引入的背景、Room的使用方式、Room的实现原理猜想验证、Room的源码原理探索总结。 本文,我们将其中牵扯到的课外知识点 or 过程中没有说到的知识点,进行一下单独的总结。 题外话:扩展知识点总结 1. 抽象工厂的设计模式应用 在源码探索…...
中国电子学会2023年03月份青少年软件编程Scratch图形化等级考试试卷三级真题(含答案)
2023-03 Scratch三级真题 分数:100 题数:38 测试时长:60min 一、单选题(共25题,共50分) 1.计算“248……128”,用变量n表示每项,根据变化规律,变量n的赋值用下列哪个最合适?&am…...
基于数字孪生的水厂可视化平台建设:架构与实践
分享大纲: 1、数字孪生水厂可视化平台建设背景 2、数字孪生水厂可视化平台建设架构 3、数字孪生水厂可视化平台建设成效 近几年,数字孪生水厂的建设开展的如火如荼。作为提升水厂管理效率、优化资源的调度手段,基于数字孪生的水厂可视化平台的…...
SpringBoot+uniapp 的 Champion 俱乐部微信小程序设计与实现,论文初版实现
摘要 本论文旨在设计并实现基于 SpringBoot 和 uniapp 的 Champion 俱乐部微信小程序,以满足俱乐部线上活动推广、会员管理、社交互动等需求。通过 SpringBoot 搭建后端服务,提供稳定高效的数据处理与业务逻辑支持;利用 uniapp 实现跨平台前…...
【配置 YOLOX 用于按目录分类的图片数据集】
现在的图标点选越来越多,如何一步解决,采用 YOLOX 目标检测模式则可以轻松解决 要在 YOLOX 中使用按目录分类的图片数据集(每个目录代表一个类别,目录下是该类别的所有图片),你需要进行以下配置步骤&#x…...
【HTML-16】深入理解HTML中的块元素与行内元素
HTML元素根据其显示特性可以分为两大类:块元素(Block-level Elements)和行内元素(Inline Elements)。理解这两者的区别对于构建良好的网页布局至关重要。本文将全面解析这两种元素的特性、区别以及实际应用场景。 1. 块元素(Block-level Elements) 1.1 基本特性 …...
全面解析各类VPN技术:GRE、IPsec、L2TP、SSL与MPLS VPN对比
目录 引言 VPN技术概述 GRE VPN 3.1 GRE封装结构 3.2 GRE的应用场景 GRE over IPsec 4.1 GRE over IPsec封装结构 4.2 为什么使用GRE over IPsec? IPsec VPN 5.1 IPsec传输模式(Transport Mode) 5.2 IPsec隧道模式(Tunne…...
GitFlow 工作模式(详解)
今天再学项目的过程中遇到使用gitflow模式管理代码,因此进行学习并且发布关于gitflow的一些思考 Git与GitFlow模式 我们在写代码的时候通常会进行网上保存,无论是github还是gittee,都是一种基于git去保存代码的形式,这样保存代码…...
省略号和可变参数模板
本文主要介绍如何展开可变参数的参数包 1.C语言的va_list展开可变参数 #include <iostream> #include <cstdarg>void printNumbers(int count, ...) {// 声明va_list类型的变量va_list args;// 使用va_start将可变参数写入变量argsva_start(args, count);for (in…...
HubSpot推出与ChatGPT的深度集成引发兴奋与担忧
上周三,HubSpot宣布已构建与ChatGPT的深度集成,这一消息在HubSpot用户和营销技术观察者中引发了极大的兴奋,但同时也存在一些关于数据安全的担忧。 许多网络声音声称,这对SaaS应用程序和人工智能而言是一场范式转变。 但向任何技…...
VisualXML全新升级 | 新增数据库编辑功能
VisualXML是一个功能强大的网络总线设计工具,专注于简化汽车电子系统中复杂的网络数据设计操作。它支持多种主流总线网络格式的数据编辑(如DBC、LDF、ARXML、HEX等),并能够基于Excel表格的方式生成和转换多种数据库文件。由此&…...
【UE5 C++】通过文件对话框获取选择文件的路径
目录 效果 步骤 源码 效果 步骤 1. 在“xxx.Build.cs”中添加需要使用的模块 ,这里主要使用“DesktopPlatform”模块 2. 添加后闭UE编辑器,右键点击 .uproject 文件,选择 "Generate Visual Studio project files",重…...
