当前位置: 首页 > news >正文

SQL进阶day10————多表查询

目录

1嵌套子查询

1.1月均完成试卷数不小于3的用户爱作答的类别

1.2月均完成试卷数不小于3的用户爱作答的类别

​编辑1.3 作答试卷得分大于过80的人的用户等级分布

2合并查询

2.1每个题目和每份试卷被作答的人数和次数

2.2分别满足两个活动的人

3连接查询

3.1满足条件的用户的试卷完成数和题目练习数

3.2 每个6/7级用户活跃情况

1嵌套子查询

1.1月均完成试卷数不小于3的用户爱作答的类别

我的代码:思路就是这么个思路,反正没有搞出来当月均完成试卷数

select tag,count(submit_time) tag_cnt
from exam_record er join examination_info ei
on er.exam_id = ei.exam_id
where uid in (当月均完成试卷数>=3)
group by tag
order by tag_cnt desc

反正没有搞出来当月均完成试卷数,报错: 

大佬正确答案:

居然和我的差不多,我就分组的时候少了uid,还有按照uid进行分组。此外,作答次数=count(start_time),而不是提交次数。

select tag, count(start_time) as tag_cnt
from exam_record er inner join examination_info ei
on er.exam_id = ei.exam_id
where uid in 
(select uid
from exam_record er 
group by uid, month(start_time)
having count(submit_time) >= 3)
group by tag
order by tag_cnt desc

复盘:

(1)uid,month(submit_time)是啥呢,如果原来只是按照month(submit_time)进行分组,1002,1003,1005都有多个

 (2)如果按照uid,month(submit_time)进行分组,情况如下

(3)这么如果只是按照month(submit_time) 分组,uid,month(submit_time)只有9和null两种情况,当使用GROUP BY子句时,NULL值将被视为一个独立的分组,并在结果集中显示一个额外的分组来表示它。

(4)结果显示只有1002,1005这两个用户满足要求,然后查找这两个用户的作答的类别及作答次数。

(5)验证:where uid =1002 or uid = 1005  等价于 子查询的效果

还有一种大佬做法是:

select tag,count(start_time) tag_cnt
from exam_record er join examination_info ei
on er.exam_id = ei.exam_id
-- where uid =1002 or uid = 1005 
WHERE er.uid IN (SELECT uidFROM exam_recordGROUP BY uidHAVING COUNT(submit_time) / COUNT(DISTINCT DATE_FORMAT(submit_time, "%Y%m")) >= 3
)
group by tag
order by tag_cnt desc

 这样出来的两个用户也是1002和1005:

  • 相当于:月均完成试卷数 = 总完成次数/哪些月份提交了数据

COUNT(DISTINCT DATE_FORMAT(submit_time, "%Y%m"))=1,所以答案一样的。

COUNT(DISTINCT DATE_FORMAT(submit_time, "%Y%m"))中的distinct很重要:

1.2月均完成试卷数不小于3的用户爱作答的类别

我的代码:答案错误,但是我能发现的的改了,

(1)SQL类,(2)当天,(3)作答人数

select er.exam_id,
any_value(count(er.submit_time)) uv,
round(avg(er.score),1) avg_score
from examination_info ei join exam_record er
on ei.exam_id = er.exam_id
where ei.tag = "SQL" 
and day(submit_time)=day(release_time)
and er.uid in 
(select uid 
from user_info
where level > 5)
group by er.exam_id
order by uv desc,avg_score asc

正确代码:

select er.exam_id,
any_value(count(distinct er.uid)) uv,
round(avg(er.score),1) avg_score
from examination_info ei join exam_record er
on ei.exam_id = er.exam_id
where ei.tag = "SQL" 
and date_format(submit_time,'%Y%m%d')=date_format(release_time,'%Y%m%d')
and er.uid in 
(select uid 
from user_info
where level > 5)
group by er.exam_id
order by uv desc,avg_score asc

复盘:

(1)同一天,不能用day函数,0901和0201的day都是1,但是不是同一天。

(2)计算人数时,要加distinct才对:

原数据有这种离谱的情况??

1.3 作答试卷得分大于过80的人的用户等级分布

我的正确代码:直接三表连接

select level,count(level) level_cnt
from user_info u 
join exam_record er
on u.uid = er.uid
join examination_info ei
on ei.exam_id = er.exam_id
where ei.tag = 'SQL'
and er.score>80
group by level

嵌套子查询的方法代码:

SELECT level, 
COUNT(level) AS level_cnt
FROM user_info
WHERE uid IN (SELECT DISTINCT uidFROM exam_recordWHERE score > 80AND exam_id IN (SELECT exam_id FROM examination_info WHERE tag = 'SQL'))
GROUP BY level
ORDER BY level_cnt DESC;

2合并查询

2.1每个题目和每份试卷被作答的人数和次数

我的代码:分别查询然后用union all合并起来,但是答案错了

select exam_id tid,
count(distinct er.uid) uv,
count(distinct pr.submit_time) pv
from exam_record er join practice_record pr
using(uid)
group by exam_idunion allselect question_id tid,
count(distinct er.uid) uv,
count(distinct pr.submit_time) pv
from exam_record er join practice_record pr
using(uid)
group by question_id

正确答案:

select * from 
(SELECT exam_id tid,count(DISTINCT uid) uv,count(uid) pv from exam_record
group by exam_id
order by uv desc,pv desc)a
UNION ALL
SELECT * FROM
(SELECT question_id tid,count(DISTINCT uid) uv,count(uid) pv from practice_record
GROUP BY question_id
order by uv desc,pv desc)b

我的代码改正:这个题最后不要合并,题目和试卷在不同的表里,分别查询在合并就好了

select exam_id tid,
count(distinct er.uid) uv,
count(er.uid) pv
from exam_record er
group by exam_idunion allselect question_id tid,
count(distinct pr.uid) uv,
count(pr.uid) pv
from practice_record pr
group by question_id

还没排序:

但是使用 union 和 多个order by 不加括号 【报错】,order by 在 union 连接的子句不起作用,但是在子句的子句中起作用。

方法一:所以加两个order的话正确要这样写:

#正确代码
select * from 
(
select exam_id as tid,count(distinct uid) as uv,count(uid) as pv
from exam_record a
group by exam_id
order by uv desc, pv desc
) a
union
select * from 
(
select question_id as tid,count(distinct uid) as uv,count(uid) as pv
from practice_record b
group by question_id
order by uv desc, pv desc
) attr

方法二:或者利用left(str,length) 函数: str左边开始的长度为 length 的子字符串,在本例中为‘9’和‘8’。

order by left(tid,1) desc,uv desc,pv desc

解释:试卷编号以‘9’开头、题目编号以‘8’开头,对编号进行降序就是对"试卷"和"题目"分别进行排序。

(#每份试卷被作答的人数和次数selectexam_id as tid,count(distinct uid) as uv,count(*) as pv
from exam_record
group by exam_id
)
union
(#每个题目被作答的人数和次数selectquestion_id as tid,count(distinct uid) as uv,count(*) as pv
from practice_record
group by question_id
)
#分别按照"试卷"和"题目"的uv & pv降序显示
order by left(tid,1) desc,uv desc,pv desc

2.2分别满足两个活动的人

我的垃圾代码:不知道新的值怎么弄

(select uidfrom exam_recordgroup by 1001having score>85
)tselect uid	t.activity
from examination_info ei join exam_record er
on ei.exam_id = er.exam_id

大佬代码:

(select uid,'activity1' as activity
from exam_record er
where year(start_time)='2021'
group by uid
having min(score)>=85)
union ALL
(select uid,'activity2' as activity
from exam_record er left join examination_info ei on er.exam_id=ei.exam_id
where year(start_time)='2021' and ei.difficulty='hard' and score>=80 
and timestampdiff(second,er.start_time,er.submit_time)<= ei.duration*30
group by uid)
order by uid;

复盘:

(1)select uid,'activity1' as activity...,这样就把activity这一列就设置出来了。

(2)时间差函数:timestampdiff,如计算差多少分钟,timestampdiff(minute,时间1,时间2),是时间2-时间1,单位是minute。

这里是至少有一次用了一半时间就完成:

完成时间<=考试时长/2 (单位为分钟minute)

完成时间<=考试时长*60/2 =考试时长*30(单位为秒second

timestampdiff(second,er.start_time,er.submit_time)<= ei.duration*30

(3)每次试卷得分都能到85分,相当于最低分min>=85

3连接查询

3.1满足条件的用户的试卷完成数和题目练习数

我的报错代码:看来不是这么简单粗暴的事情 

select u.uid,
count(er.submit_time) exam_cnt,
count(pr.submit_time) question_cnt
from user_info u join exam_record er
on u.uid = er.uid
join practice_record pr
on pr.uid = u.uid
join examination_info ei
on ei.exam_id = er.exam_id
where year(er.submit_time)='2021'
group by u.uid
having ei.tag = 'SQL'
and ei.difficulty = 'hard'
and u.level = 7
and avg(er.score)>80

正确代码:

# select er.uid as uid,
# count(distinct er.submit_time) as exam_cnt,
# count(distinct pr.submit_time) as question_cnt
select er.uid as uid,
count(distinct er.exam_id) as exam_cnt,
count(distinct pr.id) as question_cntfrom exam_record er 
left join practice_record pr 
on er.uid=pr.uid 
and year(er.submit_time)=2021 
and year(pr.submit_time)=2021where er.uid in(select er.uidfrom exam_record er left join examination_info ei on er.exam_id = ei.exam_idleft join user_info ui on er.uid = ui.uid where tag='SQL' and difficulty='hard' and level = 7group by er.uidhaving avg(score) > 80) 
group by er.uid
order by exam_cnt,question_cnt desc

复盘:

有4个表,很多个条件

(1)先通过子查询中连接,er,ui和ei筛选出高难SQL试卷得分平均值大于80并且是7级的红名大佬(返回用户uid)

(2) 再统计这些大佬2021年试卷总完成次数,和题目总练习次数

(3)注意第(2)步中连接是左连接,不应该出现试卷为null,题目不为null的情况!

from exam_record er left join practice_record pr

(4)不懂为什么不能用 er.submit_time, pr.submit_time来计算

# select er.uid as uid,
# count(distinct er.submit_time) as exam_cnt,
# count(distinct pr.submit_time) as question_cnt
select er.uid as uid,
count(distinct er.exam_id) as exam_cnt,
count(distinct pr.id) as question_cnt

3.2 每个6/7级用户活跃情况

我的错误代码:

总活跃月份数?其他都是2021年的,活跃是啥意思?

select er.uid,
# act_month_total,
count(er.start_time) act_days_2021,
count(er.submit_time) act_days_2021_exam,
count(pr.submit_time) act_days_2021_question
from exam_record er left join practice_record pr
on er.uid=pr.uid
where year(er.submit_time)=2021
and er.uid in
(select uid 
from user_info
where level = 7 or level = 6)
group by er.uid

正确代码

selectuser_info.uid,count(distinct act_month) as act_month_total,count(distinct casewhen year (act_time) = '2021' then act_dayend) as act_days_2021,count(distinct casewhen year (act_time) = '2021'and tag = 'exam' then act_dayend) as act_days_2021_exam,count(distinct casewhen year (act_time) = '2021'and tag = 'question' then act_dayend) as act_days_2021_question
from(SELECTuid,exam_id as ans_id,start_time as act_time,date_format (start_time, '%Y%m') as act_month,date_format (start_time, '%Y%m%d') as act_day,'exam' as tagfromexam_recordUNION ALLselectuid,question_id as ans_id,submit_time as act_time,date_format (submit_time, '%Y%m') as act_month,date_format (submit_time, '%Y%m%d') as act_day,'question' as tagfrompractice_record) totalright join user_info on total.uid = user_info.uid
whereuser_info.level in (6, 7)
group byuser_info.uid
order byact_month_total desc,act_days_2021 desc

复盘

(1)case when是关键

(2)2021年活跃天数 = 2021年试卷作答活跃天数 + 2021年答题活跃天数

则 exam as tag 和 practice as tag,自定义一列,为了区分是考试还是练习,便于区别计算

(3)右连接 total     right join user_info      on total.uid = user_info.uid

因为自组合的total表:没有1003

原本的user_info表:

但是6/7级的大佬中是有1003的

 

相关文章:

SQL进阶day10————多表查询

目录 1嵌套子查询 1.1月均完成试卷数不小于3的用户爱作答的类别 1.2月均完成试卷数不小于3的用户爱作答的类别 ​编辑1.3 作答试卷得分大于过80的人的用户等级分布 2合并查询 2.1每个题目和每份试卷被作答的人数和次数 2.2分别满足两个活动的人 3连接查询 3.1满足条件…...

debug调试_以Pycharm为例

文章目录 作用步骤打断点调试调试窗口 作用 主要是检查逻辑错误&#xff0c;而非语法错误。 步骤 打断点 在需要调试的代码行前打断点&#xff0c;执行后会停顿在断点位置&#xff08;不运行&#xff09; 调试 右键“debug”&#xff0c;或者直接点击右上角的小虫子 调试…...

wms第三方海外仓系统:如何为中小型海外仓注入新活力

对于中小型海外仓来说&#xff0c;想在大型集团海外仓同台竞争中获得优胜&#xff0c;提升其管理效率是非常关键的一环。 我们所熟知的wms系统&#xff0c;也就是第三方成熟海外仓系统&#xff0c;正是这些海外仓企业提升管理水平、降低成本的重要工具。 1、wms第三方海外仓系…...

html是什么?http是什么?

html Html是什么&#xff1f;http是什么&#xff1f; Html 超文本标记语言&#xff1b;负责网页的架构&#xff1b; http(&#xff08;HyperText Transfer Protocol&#xff09;超文本传输协议&#xff1b; https&#xff08;全称&#xff1a;Hypertext Transfer Protocol …...

L1-007 念数字js实现

异步解法 const readline require("readline"); const rl readline.createInterface({input: process.stdin,output: process.stdout, }); const input_arr [];//储存数据 rl.on(line, function (line) {input_arr.push(line); } ); rl.on(close, function () {/…...

Perl 运算符

Perl 运算符 Perl 是一种功能强大的编程语言&#xff0c;广泛应用于系统管理、网络编程、GUI 创建、数据库访问等众多领域。Perl 的语法灵活&#xff0c;支持多种编程范式&#xff0c;包括过程式、面向对象和函数式编程。在 Perl 中&#xff0c;运算符扮演着重要的角色&#x…...

语法04 C++ 标准输入语句

标准输入 使用格式&#xff1a;cin >> 输入的意思就是把一个值放到变量里面去&#xff0c;也就是变量的赋值&#xff0c;这个值是由我们自己输入的。 (注意:输入变量前要先定义&#xff0c;输入完之后要按Enter键。) 输入多个变量&#xff0c;与输出类似&#xff0c;…...

python数据分析--- ch6-7 python容器类型的数据及字符串

python数据分析---ch6-7 python容器类型的数据及字符串 1. Ch6--容器类型的数据1.1 序列1.1.1 序列的索引操作1.1.2 加和乘操作1.1.3 切片操作1.1.4 成员测试 1.2 列表1.2.1 创建列表1.2.2 追加元素1.2.3 插入元素1.2.4 替换元素1.2.5 删除元素1.2.6 列表排序&#xff08;1&…...

【Linux取经路】守护进程

文章目录 一、前台进程和后台进程二、Linux 的进程间关系三、setsid——将当前进程设置为守护进程四、daemon——设置为守护进程五、结语 一、前台进程和后台进程 Linux 中每一次用户登录都是一个 session&#xff0c;一个 session 中只能有一个前台进程在运行&#xff0c;键盘…...

Nginx之文件下载服务器

1.概述 在对外分享文件时&#xff0c;利用Nginx搭建一个简单的下 载文件管理服务器&#xff0c;文件分享就会变得非常方便。利 用Nginx的诸多内置指令可实现自动生成下载文件列表 页、限制下载带宽等功能。配置样例如下&#xff1a; server {listen 8080;server_name localhos…...

OpenCV学习(4.11) OpenCV中的图像转换

1. 目标 在本节中&#xff0c;我们将学习 使用OpenCV查找图像的傅立叶变换利用Numpy中可用的FFT功能傅立叶变换的一些应用我们将看到以下函数&#xff1a;**cv.dft()** &#xff0c;**cv.idft()** 等 理论 傅立叶变换用于分析各种滤波器的频率特性。对于图像&#xff0c;使用…...

2024.6.13每日一题

LeetCode 子序列最大优雅度 题目链接&#xff1a;2813. 子序列最大优雅度 - 力扣&#xff08;LeetCode&#xff09; 题目描述 给你一个长度为 n 的二维整数数组 items 和一个整数 k 。 items[i] [profiti, categoryi]&#xff0c;其中 profiti 和 categoryi 分别表示第 i…...

Linux命令详解(2)

文本处理是Linux命令行的重要应用之一。通过一系列强大的命令&#xff0c;用户可以轻松地对文本文件进行编辑、查询和转换。 cat&#xff1a; 这个命令用于查看文件内容。它可以一次性显示整个文件&#xff0c;或者分页显示。此外&#xff0c;cat 还可以用于合并多个文件的内容…...

iOS ReactiveCocoa MVVM

学习了在MVVM中如何使用RactiveCocoa&#xff0c;简单的写上一个demo。重点在于如何在MVVM各层之间使用RAC的信号来更方便的在各个层之间进行响应式数据交互。 demo需求&#xff1a;一个登录界面(登录界面只有账号和密码都有输入&#xff0c;登录按钮才可以点击操作)&#xff0…...

图文解析ASN.1中BER编码:结构类型、编码方法、编码实例

本文将详细介绍ASN.1中的BER编码规则&#xff0c;包括其编码机制、数据类型表示、以及如何将复杂的数据结构转换为二进制数据。通过本文的阅读&#xff0c;读者将对ASN.1中的BER编码有一个全面的理解。 目录 一.引言 二.BER编码基本结构 ▐ 1. 类型域&#xff08;Type&#…...

jQuery如何停止动画队列

在jQuery中&#xff0c;你可以使用.stop()方法来停止动画队列。.stop()方法有几个可选的参数&#xff0c;可以用来控制停止动画的方式。 以下是.stop()方法的基本用法和一些参数选项&#xff1a; 无参数&#xff1a;立即停止当前动画&#xff0c;并跳到最后的状态。后续的动画…...

vue3+electron搭建桌面软件

vue3electron开发桌面软件 最近有个小项目, 客户希望像打开 网易云音乐 那么简单的运行起来系统. 前端用 Vue 会比较快一些, 因此决定使用 electron 结合 Vue3 的方式来完成该项目. 然而, 在实施过程中发现没有完整的博客能够记录从创建到打包的流程, 摸索一番之后, 随即梳理…...

oracle常用经典SQL查询

oracle常用经典SQL查询(转贴) oracle常用经典SQL查询 常用SQL查询&#xff1a; 1、查看表空间的名称及大小 select t.tablespace_name, round(sum(bytes/(1024*1024)),0) ts_size from dba_tablespaces t, dba_data_files d where t.tablespace_name d.tablespace_name grou…...

Android shell 常用 debug 命令

目录 1、查看版本2、am 命令3、pm 命令4、dumpsys 命令5、sed命令6、log定位查看APK进程号7、log定位使用场景 1、查看版本 1.1、Android串口终端执行 getprop ro.build.version.release #获取Android版本 uname -a #查看linux内核版本信息 uname -r #单独查看内核版本 1.2、…...

Unity3D Shader数据传递语法详解

在Unity3D中&#xff0c;Shader是用于渲染图形的一种程序&#xff0c;它定义了物体在屏幕上的外观。Shader通过接收输入数据&#xff08;如顶点位置、纹理坐标、光照信息等&#xff09;并计算像素颜色来工作。为了使得Shader能够正确运行并产生期望的视觉效果&#xff0c;我们需…...

SpringBoot-17-MyBatis动态SQL标签之常用标签

文章目录 1 代码1.1 实体User.java1.2 接口UserMapper.java1.3 映射UserMapper.xml1.3.1 标签if1.3.2 标签if和where1.3.3 标签choose和when和otherwise1.4 UserController.java2 常用动态SQL标签2.1 标签set2.1.1 UserMapper.java2.1.2 UserMapper.xml2.1.3 UserController.ja…...

XML Group端口详解

在XML数据映射过程中&#xff0c;经常需要对数据进行分组聚合操作。例如&#xff0c;当处理包含多个物料明细的XML文件时&#xff0c;可能需要将相同物料号的明细归为一组&#xff0c;或对相同物料号的数量进行求和计算。传统实现方式通常需要编写脚本代码&#xff0c;增加了开…...

Java 语言特性(面试系列2)

一、SQL 基础 1. 复杂查询 &#xff08;1&#xff09;连接查询&#xff08;JOIN&#xff09; 内连接&#xff08;INNER JOIN&#xff09;&#xff1a;返回两表匹配的记录。 SELECT e.name, d.dept_name FROM employees e INNER JOIN departments d ON e.dept_id d.dept_id; 左…...

K8S认证|CKS题库+答案| 11. AppArmor

目录 11. AppArmor 免费获取并激活 CKA_v1.31_模拟系统 题目 开始操作&#xff1a; 1&#xff09;、切换集群 2&#xff09;、切换节点 3&#xff09;、切换到 apparmor 的目录 4&#xff09;、执行 apparmor 策略模块 5&#xff09;、修改 pod 文件 6&#xff09;、…...

Appium+python自动化(十六)- ADB命令

简介 Android 调试桥(adb)是多种用途的工具&#xff0c;该工具可以帮助你你管理设备或模拟器 的状态。 adb ( Android Debug Bridge)是一个通用命令行工具&#xff0c;其允许您与模拟器实例或连接的 Android 设备进行通信。它可为各种设备操作提供便利&#xff0c;如安装和调试…...

从深圳崛起的“机器之眼”:赴港乐动机器人的万亿赛道赶考路

进入2025年以来&#xff0c;尽管围绕人形机器人、具身智能等机器人赛道的质疑声不断&#xff0c;但全球市场热度依然高涨&#xff0c;入局者持续增加。 以国内市场为例&#xff0c;天眼查专业版数据显示&#xff0c;截至5月底&#xff0c;我国现存在业、存续状态的机器人相关企…...

Psychopy音频的使用

Psychopy音频的使用 本文主要解决以下问题&#xff1a; 指定音频引擎与设备&#xff1b;播放音频文件 本文所使用的环境&#xff1a; Python3.10 numpy2.2.6 psychopy2025.1.1 psychtoolbox3.0.19.14 一、音频配置 Psychopy文档链接为Sound - for audio playback — Psy…...

ardupilot 开发环境eclipse 中import 缺少C++

目录 文章目录 目录摘要1.修复过程摘要 本节主要解决ardupilot 开发环境eclipse 中import 缺少C++,无法导入ardupilot代码,会引起查看不方便的问题。如下图所示 1.修复过程 0.安装ubuntu 软件中自带的eclipse 1.打开eclipse—Help—install new software 2.在 Work with中…...

关于 WASM:1. WASM 基础原理

一、WASM 简介 1.1 WebAssembly 是什么&#xff1f; WebAssembly&#xff08;WASM&#xff09; 是一种能在现代浏览器中高效运行的二进制指令格式&#xff0c;它不是传统的编程语言&#xff0c;而是一种 低级字节码格式&#xff0c;可由高级语言&#xff08;如 C、C、Rust&am…...

python报错No module named ‘tensorflow.keras‘

是由于不同版本的tensorflow下的keras所在的路径不同&#xff0c;结合所安装的tensorflow的目录结构修改from语句即可。 原语句&#xff1a; from tensorflow.keras.layers import Conv1D, MaxPooling1D, LSTM, Dense 修改后&#xff1a; from tensorflow.python.keras.lay…...