〇、内容

时间比较2-2

联合结果各自排序

查询列和GROUP BY

一、嵌套子查询

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

自己的答案【错误】:

SELECT tag,
COUNT(A.start_time) AS tag_cnt
FROM (
-- 查询 “当月均完成试卷数”不小于3的用户们
SELECT *
FROM exam_record
GROUP BY uid
HAVING COUNT(*)>=3
) A
RIGHT JOIN examination_info B
ON A.exam_id=B.exam_id
GROUP BY tag
ORDER BY tag_cnt DESC

答案:【group by的字段一定要出现在查询列中,*不算】

SELECT tag,
COUNT(B.tag) AS tag_cnt
FROM exam_record A
RIGHT JOIN examination_info B
ON A.exam_id=B.exam_id
WHERE uid IN (
SELECT uid
FROM exam_record
GROUP BY uid
-- 统计当前用户完成试卷总数
-- 统计该用户有完成试卷的月份数
HAVING COUNT(submit_time) / COUNT(DISTINCT DATE_FORMAT(submit_time, "%Y%m")) >= 3
)
GROUP BY tag
ORDER BY tag_cnt DESC

2、试卷发布当天作答人数和平均分【☆】

自己的答案【错误】

SELECT
exam_id,
SUM(IF(DATE_FORMAT((submit_time,"%Y%m")==DATE_FORMAT(release_time,"%Y%m") and level>=5,1,0))) AS uv,
ROUND(AVG(score),1) AS avg_score
FROM user_info A
JOIN examination_info
JOIN exam_record
ON
A.uid=C.uid
AND
B.exam_id=C.exam_id
WHERE
tag="SQL"
GROUP BY exam_id
ORDER BY uv DESC,avg_score ASC

正确答案:【判断相等用一个等号】

SELECT
C.exam_id,
COUNT(DISTINCT C.uid) AS uv,
ROUND(AVG(score),1) AS avg_score
FROM user_info A
JOIN examination_info B
JOIN exam_record C
ON
A.uid=C.uid
AND
B.exam_id=C.exam_id
WHERE
tag="SQL"
AND
level>5
AND
DATE(submit_time)=DATE(release_time)
GROUP BY C.exam_id
ORDER BY uv DESC,avg_score ASC

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

SELECT
level,
COUNT(*) AS level_cnt
FROM user_info A
JOIN examination_info B
JOIN exam_record C
-- NATURAL/FULL/CROSS
ON A.uid=C.uid
AND B.exam_id=C.exam_id
WHERE
tag="SQL"
AND
score>80
GROUP BY level
ORDER BY level_cnt DESC

二、合并查询

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

答案:【UNION和ORDER BY混用会被覆盖】

-- order by可以存在 union的字句里面,但是功能不会生效
SELECT * FROM
(SELECT
exam_id AS tid,
COUNT(DISTINCT uid) AS uv,
COUNT(exam_id) AS pv
FROM exam_record
GROUP BY tid
ORDER BY uv DESC,pv DESC) AS A
UNION
SELECT * FROM
(SELECT
question_id AS tid,
COUNT(DISTINCT uid) AS uv,
COUNT(question_id) AS pv
FROM practice_record
GROUP BY tid
ORDER BY uv DESC,pv DESC) AS B

2、分别满足两个活动的人

思路:TIMESTAMPDIFF(SECOND,start_time,submit_time)<=duration*30,时间比较用SECOND和TIMESTAMPDIFF

至少有一次不需要聚合函数,在where中即可实现,先查找出符合要求的,再进行分组

全部需要用聚合函数,先分组再having

-- 输出2021年里,所有每次试卷得分都能到85分的人以及至少有一次
-- 用了一半时间就完成高难度试卷且分数大于80的人的id和活动号,按用户ID排序输出。
-- 全部成绩大于85可以用最小成绩>85表示
(SELECT
uid,
"activity1" AS activity
FROM exam_record
GROUP BY uid
HAVING MIN(score)>=85)
UNION ALL
(SELECT
uid,
"activity2" AS activity
FROM exam_record B
LEFT JOIN examination_info A
ON A.exam_id=B.exam_id
WHERE
TIMESTAMPDIFF(SECOND,start_time,submit_time)<=duration*30
AND
score>=80
AND
difficulty="hard"
GROUP BY uid)
ORDER BY uid

三、连接查询

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

自己的写法【错误】

SELECT
A.uid,
COUNT(DISTINCT C.uid) AS exam_cnt,
COUNT(DISTINCT D.uid) AS question_cnt
FROM user_info A
JOIN examination_info B
JOIN exam_record C
JOIN practice_record D
ON
A.uid=C.uid
AND
A.uid=D.uid
AND
B.exam_id=C.exam_id
WHERE
level=7
AND
tag="SQL"
AND
difficulty="hard"
AND
(YEAR(C.submit_time)=2021
OR
YEAR(D.submit_time)=2021)
GROUP BY A.uid
HAVING -- 子句不能出现year
AVG(C.score)>80
ORDER BY exam_cnt ASC,question_cnt DESC

答案:

-- 先分别写出2021年分组后的试卷完成情况和题目练习情况
-- 再查询出高难度SQL试卷得分平均值大于80并且是7级的红名大佬
select
uid,
exam_cnt,
if(question_cnt is null, 0, question_cnt)
from
(select
uid,
count(submit_time) as exam_cnt
from exam_record
where YEAR(submit_time) = 2021
group by uid) t left join (select
uid,
count(submit_time) as question_cnt
from practice_record
where YEAR(submit_time) = 2021
group by uid) t2 using(uid) where uid in
(
select
uid
from exam_record
join examination_info using(exam_id)
join user_info using(uid)
where tag = 'SQL' and difficulty = 'hard' and `level` = 7
group by uid
having avg(score) >= 80
)
order by exam_cnt asc, question_cnt desc

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

自己分步写的:

-- 查询出6/7级用户
SELECT
uid
FROM user_info
WHERE
level=6
OR
level=7 -- 查询总活跃月份数
SELECT
uid,
COUNT(DISTINCT act_month) AS act_month_total
FROM
(SELECT
uid,
DATE_FORMAT(start_time,"%Y%m") AS act_month
FROM exam_record
UNION ALL
SELECT
uid,
DATE_FORMAT(submit_time,"%Y%m") AS act_month
FROM practice_record) t1
GROUP BY uid -- 查询2021年活跃天数(UNION?)
SELECT
uid,
COUNT(DISTINCT act_days) AS act_days_2021
FROM
((SELECT
uid,
DATE(start_time) AS act_days
FROM exam_record
WHERE
YEAR(start_time)=2021)
UNION ALL
(SELECT
uid,
DATE(submit_time) AS act_days
FROM practice_record
WHERE
YEAR(submit_time)=2021)) t1
GROUP BY uid -- 查询试卷作答活跃天数
SELECT
uid,
COUNT(DISTINCT DATE(start_time)) AS act_month_total
FROM exam_record
WHERE YEAR(start_time)=2021
GROUP BY uid -- 2021年答题活跃天数
SELECT
uid,
COUNT(DISTINCT DATE(submit_time)) AS act_month_total
FROM practice_record
WHERE YEAR(submit_time)=2021
GROUP BY uid

答案:

select
ui.uid,
count(distinct left(s,6)) as act_month_total,
count(distinct if(left(s,4)='2021',right(s,4),null)) as act_days_2021,
count(distinct if(left(s,4)='2021' and tag='e',right(s,4),null)) as act_days_2021_exam,
count(distinct if(left(s,4)='2021' and tag='p',right(s,4),null)) as act_days_2021_question
from (
select uid,DATE_FORMAT(submit_time,'%Y%m%d') as s,'p' tag from practice_record pr
union all
SELECT uid,DATE_FORMAT(start_time,'%Y%m%d') as s,'e' as tag from exam_record er
)mon
right join user_info ui
on ui.uid = mon.uid
where ui.level >5
group by uid
order by act_month_total DESC,act_days_2021 desc

【SQL进阶】【分步写、联合各自排序、TIMESTAMPDIFF时间比较】Day04:多表查询的更多相关文章

  1. 《SQL 进阶教程》 自连接分组排序:练习题1-2-2

    分组排序 SELECT d1.district, d1. NAME, (SELECT COUNT(d2.price) FROM district_products d2 WHERE d2.price ...

  2. SQLYog执行SQL脚本提示:错误代码: 1067 - Invalid default value for '数据库表'查询:解决办法

    强烈建议:完全卸载当前版本MySQL,重新安装5.6及以上版本 完全卸载方法:https://jingyan.baidu.com/article/3d69c551611290f0ce02d77b.ht ...

  3. 《SQL基础教程》+ 《SQL进阶教程》 学习笔记

    写在前面:本文主要注重 SQL 的理论.主流覆盖的功能范围及其基本语法/用法.至于详细的 SQL 语法/用法,因为每家 DBMS 都有些许不同,我会在以后专门介绍某款DBMS(例如 PostgreSQ ...

  4. 【SQL进阶】03.执行计划之旅1 - 初探

    听到大牛们说执行计划,总是很惶恐,是对知识的缺乏的惶恐,所以必须得学习执行计划,以减少对这一块知识的惶恐,下面是对执行计划的第一讲-理解执行计划. 本系列[T-SQL]主要是针对T-SQL的总结. S ...

  5. MySQL:SQL进阶

    一.数据库相关理论 1.系统数据库 information_schema: 虚拟库,不占用磁盘空间,存储的是数据库启动后的一些参数,如用户表信息.列信息.权限信息.字符信息等performance_s ...

  6. mysql基础sql进阶

    回顾前面的基础命令语句 修改数据表 添加字段: alter table 表名 add 字段名 列类型[not null|null][primary key][unique][auto_incremen ...

  7. SQL优化之SQL 进阶技巧(上)

    由于工作需要,最近做了很多 BI 取数的工作,需要用到一些比较高级的 SQL 技巧,总结了一下工作中用到的一些比较骚的进阶技巧,特此记录一下,以方便自己查阅,主要目录如下: SQL 的书写规范 SQL ...

  8. SQL进阶随笔--case用法(一)

    SQL进阶一整个是根据我看了pdf版本的整理以及自己的见解整理.后期也方便我自己查看和复习. CASE 表达式 CASE 表达式是从 SQL-92 标准开始被引入的.可能因为它是相对较新的技术,所以尽 ...

  9. SQL进阶语法的多表操作

    AS别名 多张表联合操作,如果表多,字段名长,不方便阅读.这里我们可以使用  as  关键字来对字段名设置别名. as也可以省略,看个人喜好,在这里我还是支持把 as 写上,这样我们在面对复杂的SQL ...

  10. SQL优化之SQL 进阶技巧(下)

    上文( SQL优化之SQL 进阶技巧(上) )我们简述了 SQL 的一些进阶技巧,一些朋友觉得不过瘾,我们继续来下篇,再送你 10 个技巧 一. 使用延迟查询优化 limit [offset], [r ...

随机推荐

  1. Java开发学习(三十五)----SpringBoot快速入门及起步依赖解析

    一.SpringBoot简介 SpringBoot 是由 Pivotal 团队提供的全新框架,其设计目的是用来简化 Spring 应用的初始搭建以及开发过程. 使用了 Spring 框架后已经简化了我 ...

  2. Django 之视图层

    JsonResponse 1 json格式的数据有什么用 前后端数据交互需要使用json作为过渡,实现跨语言传输数据 2 前后端方法对应 JSON.stringify() -  json.dumps( ...

  3. Kubernetes 日志:日志收集架构

    应用程序和系统日志可以帮助我们了解集群内部的运行情况,日志对于我们调试问题和监视集群情况也是非常有用的.而且大部分的应用都会有日志记录,对于传统的应用大部分都会写入到本地的日志文件之中.对于容器化应用 ...

  4. ES重要配置解析

    path.data和path.logs 如果您使用.zip或.tar.gz存档,则data和logs 目录是子文件夹$ES_HOME.如果这些重要文件夹保留在其默认位置,则在将Elasticsearc ...

  5. centos7使用yum方式安装redis6

    yum -y install epel-release wget make gcc-c++ cd /opt wget https://download.redis.io/releases/redis- ...

  6. Portainer实用教程

    Portainer使用 Nginx 容器实现端口转发 在 WordPress 部署完成后,需要在浏览器内输入 IP:端口或域名:端口 的形式访问网站,但我们一般访问应用的时候都是希望不加端口就能访问域 ...

  7. 220501 T1 困难的图论 (tarjan 点双)

    求满足题目要求的简单环,做出图中所有的点双,用vector存储点双中的边,如果该点双满足点数=边数,就是我们想要的,求边的异或和即可:如果该点双点数小于边数,说明有不只一个环覆盖,不满足题意. 1 # ...

  8. 【NOI2016】 循环之美 题解

    Solution 由数论基础知识 答案即为$$\sum_{i = 1}^n\sum_{j = 1}^m[i \perp j][j \perp k]$$ 莫反套路可化为$$\sum_{d = 1}\mu ...

  9. Hive Beeline 命令行参数

    [hadoop@hive ~]$ beeline --help[中文版] The Beeline CLI 支持以下命令行参数: Option Description --autoCommit=[tru ...

  10. sentinel的四种流控规则介绍

    sentinel的四种流控规则介绍 今天的内容我们主要围绕四个点进行展开介绍. 流控模式 :关联.链路 流控效果 :Warm Up.排队等待 这四点具体是什么意思呢? 首先启动项目:cloud-ali ...