SQL笔试题总结

news2024/11/16 13:34:43

文章目录

  • 前言
  • 一、列转行
    • 题目:将表Student
    • 转化为下面的形式展示
    • 先放答案
    • 逐步剖析
  • 二、row_number() over() 的使用
    • 题目:统计订单交易表(orders)每个商品交易金额最高的那一条数据
    • 先放答案
    • 逐步剖析
  • 三、逐行累加
    • 题目:还是订单交易表(orders),对商品按照月份累加汇总。比如,一月份显示一月的交易金额,二月份显示一月份+二月份的交易金额
    • 先放答案
    • 逐步剖析

  

  

  

  

前言

  

本篇文章将总结博主在笔试或面试过程中碰到的比较有难度或经典的sql题目。笔试考察的大都不是很难,不像工作中那样好几个嵌套子查询,很多个表关联…可能行数很少,但绝对得多想。如果之前没碰见过,第一次做肯定会漏洞百出。会持续更新的~

  
  
  

一、列转行

  

题目:将表Student

namesubjectscore
张三语文78.0
张三数学88.0
张三英语98.0
李四语文89.0
李四数学76.0
李四英语90.0
王五语文66.0

转化为下面的形式展示

name语文数学英语总分
张三788898264
李四897690255
王五990066

  

先放答案

SELECT `name`,语文,数学,英语,总分
FROM(
	SELECT
	`name`,
	SUM(IF(SUBJECT = '语文',score,0)) AS 语文,
	SUM(IF(SUBJECT = '数学',score,0)) AS 数学,
	SUM(IF(SUBJECT = '英语',score,0)) AS 英语
	FROM student
	GROUP BY `name`)t1
LEFT JOIN(
	SELECT `name`,SUM(score) AS 总分
	FROM student
	GROUP BY `name`)t2
USING(`name`);

  

逐步剖析

1、先看总分,计算很简单,就是按名字group by 之后 sum(分数) 即可

SELECT `name`,SUM(score) AS 总分
FROM student
GROUP BY `name`
name总分
张三264
李四255
王五66

得出这样的结果
  
2、本题精髓就是怎么把 subject 这一列数据转化成一行列名。可以拿 subject 列中的数据做 if 判断的条件,创建一张只有 name列 不变,后几列是 语数英 的新表

SELECT
`name`,
IF(SUBJECT = '语文',score,0) AS 语文,
IF(SUBJECT = '数学',score,0) AS 数学,
IF(SUBJECT = '英语',score,0) AS 英语
FROM student
name语文数学英语
张三78.000
张三088.00
张三0098.0
李四89.000
李四076.00
李四0090.0
王五66.000

  
3、离最终答案不远了,用 group by + sum 就能变成没人一行且语数英三列数据合并

SELECT
`name`,
SUM(IF(SUBJECT = '语文',score,0)) AS 语文,
SUM(IF(SUBJECT = '数学',score,0)) AS 数学,
SUM(IF(SUBJECT = '英语',score,0)) AS 英语
FROM student
GROUP BY `name`
name语文数学英语
张三788898
李四897690
王五9900

这条sql就是本题精髓!!! 怕直接看看不懂,所以拆开分两步写了。

  
4、最后一步简单,把各科表和总分表关联起来就行,刚才那俩分离的sql写一起

SELECT `name`,语文,数学,英语,总分
FROM(
	SELECT
	`name`,
	SUM(IF(SUBJECT = '语文',score,0)) AS 语文,
	SUM(IF(SUBJECT = '数学',score,0)) AS 数学,
	SUM(IF(SUBJECT = '英语',score,0)) AS 英语
	FROM student
	GROUP BY `name`)t1
LEFT JOIN(
	SELECT `name`,SUM(score) AS 总分
	FROM student
	GROUP BY `name`)t2
USING(`name`);

  
  
  

二、row_number() over() 的使用

  

row_number() over() 在面试中经常和 rank() over()、dense_rank() over() 一起被问,在笔试中也经常需要用到,甚至在工作中也经常见到,反正是相当的重要!
在工作中其实用的是 row_number() over() 的变种,用 @ 。因为公司大都是MySQL5,但窗口函数在MySQL8中才出现,所以工作中都是 row_number 的思想,@的写法。关于@的使用有时间我写写。
  

题目:统计订单交易表(orders)每个商品交易金额最高的那一条数据

item_idtrade_datetrade_amount
A2021/3/11500
A2021/3/92500
A2021/2/221000
B2021/3/53000
B2021/5/95000
B2021/6/22800

item_id=商品代码  trade_date=交易日期  trade_amount=交易金额

  

先放答案

SELECT 
	item_id,
	trade_date,
	trade_amount
FROM(
	SELECT 
		item_id,
		trade_date,
		trade_amount,
		row_number() over(PARTITION BY item_id ORDER BY trade_amount DESC) AS sort
	FROM orders)t
WHERE sort = 1
item_idtrade_datetrade_amount
A2021/3/92500
B2021/5/95000

  

逐步剖析

1、因为要求每个商品的金额最高,所以分组排序必不可少。为什么不能用 group by 然后 max 呢?因为要求的是金额最高的那一条数据,而不是求最高金额,那一行数据的其他信息得保留下来。而group by 后的其他字段不用聚合函数是没法保存的,就丢失了,跟题意不符。

举个栗子吧:

SELECT item_id,MAX(trade_amount)
FROM orders
GROUP BY item_id

在这里插入图片描述
虽然能找到最高金额,但这样就缺字段了

还有这样:

SELECT item_id,trade_date,MAX(trade_amount)
FROM orders
GROUP BY item_id

这样写直接报错,因为 group by 了 item_id 这一列,那么它之外的列如果不用聚合函数直接报错

这样也是不对:

SELECT item_id,trade_date,MAX(trade_amount)
FROM orders
GROUP BY item_id,trade_date

虽然不报错,但是
在这里插入图片描述
只有 item_id 和 trade_date 都相同的才能分为一组,不符合题意

  
所以要用到 row_number() over() 进行分组排序:

SELECT 
	item_id,
	trade_date,
	trade_amount,
	row_number() over(PARTITION BY item_id ORDER BY trade_amount DESC) AS sort
FROM orders
item_idtrade_datetrade_amountsort
A2021/3/925001
A2021/3/115002
A2021/2/2210003
B2021/5/950001
B2021/3/530002
B2021/6/228003

  
2、最后子查询即可

SELECT 
	item_id,
	trade_date,
	trade_amount
FROM(
	SELECT 
		item_id,
		trade_date,
		trade_amount,
		row_number() over(PARTITION BY item_id ORDER BY trade_amount DESC) AS sort
	FROM orders)t
WHERE sort = 1

  
  
  

三、逐行累加

  

题目:还是订单交易表(orders),对商品按照月份累加汇总。比如,一月份显示一月的交易金额,二月份显示一月份+二月份的交易金额

展示结果应该为:

item_idtrade_datetrade_amount
A2021/21000
A2021/35000
B2021/33000
B2021/58000
B2021/68800

  

先放答案

SELECT
	t1.item_id AS item_id,
	t1.month AS trade_date,
	SUM(t2.trade_amount) AS trade_amount
FROM(
	SELECT
		item_id,
		DATE_FORMAT(trade_date,'%Y-%m') AS `month`,
		SUM(trade_amount) trade_amount 
	FROM orders 
	GROUP BY item_id,DATE_FORMAT(trade_date,'%Y-%m')
	ORDER BY item_id,`month`)t1
LEFT JOIN(
	SELECT
		item_id,
		DATE_FORMAT(trade_date,'%Y-%m') AS `month`,
		SUM(trade_amount) trade_amount 
	FROM orders 
	GROUP BY item_id,DATE_FORMAT(trade_date,'%Y-%m')
	ORDER BY item_id,`month`)t2
ON t1.item_id = t2.item_id
WHERE t2.month <= t1.month
GROUP BY t1.item_id,t1.month

  

逐步剖析

1、题目说:按照月份累加汇总。怎么按照月份呢,按月份分组,把相同月份的金额加起来

SELECT
	item_id,
	DATE_FORMAT(trade_date,'%Y-%m') AS `month`,
	SUM(trade_amount) trade_amount 
FROM orders 
GROUP BY item_id,DATE_FORMAT(trade_date,'%Y-%m')
ORDER BY item_id,`month`
item_idtrade_datetrade_amount
A2021/21000
A2021/34000
B2021/33000
B2021/55000
B2021/6800

因为要求不同商品不同月份汇总,所以 group by 后要用两个字段分组。

  
2、到这里已经跟结果很接近了,只要能按照 item_id(商品代码)分组然后累加即可,我首先想到了sum() over() 窗口函数

SELECT 
	item_id,
	`month`,
	SUM(trade_amount) over(PARTITION BY item_id) sums
FROM (
	SELECT
		item_id,
		DATE_FORMAT(trade_date,'%Y-%m') AS `month`,
		SUM(trade_amount) trade_amount 
	FROM orders 
	GROUP BY item_id,DATE_FORMAT(trade_date,'%Y-%m')
	ORDER BY item_id,`month`)t
GROUP BY item_id,`month`

在这里插入图片描述
但是 sum 窗口函数只能把分组内的总和计算出来填到每一列,没法做到逐行累加。到这我已经没有思路了,我就去求助了一下经理@红糖番薯,才知道可以用自连接。

我先自连接试试:

SELECT
*
FROM(
	SELECT
		item_id,
		DATE_FORMAT(trade_date,'%Y-%m') AS `month`,
		SUM(trade_amount) trade_amount 
	FROM orders 
	GROUP BY item_id,DATE_FORMAT(trade_date,'%Y-%m')
	ORDER BY item_id,`month`)t1
LEFT JOIN(
	SELECT
		item_id,
		DATE_FORMAT(trade_date,'%Y-%m') AS `month`,
		SUM(trade_amount) trade_amount 
	FROM orders 
	GROUP BY item_id,DATE_FORMAT(trade_date,'%Y-%m')
	ORDER BY item_id,`month`)t2
ON t1.item_id = t2.item_id

在这里插入图片描述
看似杂乱无章,其实有点东西

题目要求:一月份显示一月的金额,二月份显示一月份+二月份的金额

那么上面自连接的 sql 在最后也要加一个筛选条件

WHERE t2.month <= t1.month

这样使得表右半段的数据,即 t2 的数据不会超出 t1 指定的月份范围,不加时可能 t1 是第一月,而表的后半段 t2 是第二月这个情况。
加上后,表前半段 t1 的数据是某月,而后半段 t2 就是 <= t1 指定的月了,那么把 t2 月份的金额相加就是累积金额了。
怎么分组呢?按表前半段 t1 的月份分组,每一组中的表后半段 t2 就是 <= t1 的所有月份,金额和就是累积值。

SELECT
	t1.item_id AS item_id,
	t1.month AS trade_date,
	SUM(t2.trade_amount) AS trade_amount
FROM(
	SELECT
		item_id,
		DATE_FORMAT(trade_date,'%Y-%m') AS `month`,
		SUM(trade_amount) trade_amount 
	FROM orders 
	GROUP BY item_id,DATE_FORMAT(trade_date,'%Y-%m')
	ORDER BY item_id,`month`)t1
LEFT JOIN(
	SELECT
		item_id,
		DATE_FORMAT(trade_date,'%Y-%m') AS `month`,
		SUM(trade_amount) trade_amount 
	FROM orders 
	GROUP BY item_id,DATE_FORMAT(trade_date,'%Y-%m')
	ORDER BY item_id,`month`)t2
ON t1.item_id = t2.item_id
WHERE t2.month <= t1.month
GROUP BY t1.item_id,t1.month

精髓就是 group by t1 的两列,但 sum t2 的金额

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/132489.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

✿✿✿JavaScript --- jQuery框架二

目 录 1.高级事件 (1)浏览器一打开自动触发我们绑定的事件 (2) Trigger 传递数据 (3)自定义事件 (4)trigger 简写方案 (5)triggerHandler() (6)trigger和triggerHandler的区别 (7)on off one 2.动画 (1)显示 隐藏 动画 (2)队列动画 (3)下滑 上卷 (4)淡入淡出…

Nacos启动出现Error creating bean with name ‘memoryMonitor‘ 、‘externalDumpService‘

目录 &#x1f9e1;问题 &#x1f9e1;解决方法 &#x1f49f;这里是CS大白话专场&#xff0c;让枯燥的学习变得有趣&#xff01; &#x1f49f;没有对象不要怕&#xff0c;我们new一个出来&#xff0c;每天对ta说不尽情话&#xff01; &#x1f49f;好记性不如烂键盘&#x…

WSL2支持systemctl命令

文章目录背景相关知识systemdinit安装方法一&#xff1a;微软官方支持方法&#xff08;推荐&#xff09;方法二&#xff1a;安装daemonize实现参考背景 微软官方推出Windows Terminal第一时间&#xff0c;我就安装了这个终端软件。现在GitHub已经有86.8k星&#xff0c;且发布了…

一名普通Java程序员的2022的总结和2023的展望

前言今天是元旦节&#xff0c;也是2023年的第一天&#xff0c;首先祝各位亲朋好友们元旦快乐&#xff0c;在新的一年全家身体康健&#xff0c;诸事顺遂&#xff0c;阖家幸福&#xff0c;最重要的是身体健康&#xff0c;工作顺利&#xff0c;永无BUG永不加班&#xff01;&#x…

计算机组成原理【1】初识硬件

目录 考点1&#xff1a;硬件发展———————————————————————————— 一.计算机硬件的基本组成 1.早期冯诺依曼机 &#xff08;1&#xff09;冯.诺依曼计算机的特点: 2.现代计算机的结构 3.总结图 二.各个硬件的工作原理 1.寄存器MAR,MDR 2.主存…

EMNLP22 外部知识注入:Prompt-Learning for Short Text Classification

Prompt-Learning for Short Text Classification 任务形式&#xff1a;短文本分类问题&#xff0c;但是短文本的短长度、特征稀疏性和高模糊性给分类任务带来了巨大挑战。 1以往的工作&#xff0c;在注入外部信息上 大多数提示学习方法手动扩展标签词或仅考虑类别名称以纳入…

得分_UVa1585分子量_UVa1586数数字_UVa1225周期串_UVa455子序列_UVa10340

目录 P57_习题3-1_得分_UVa1585 P57_习题3-2_分子量_UVa1586 原子数范围0~99 书上给的代码 P57_习题3-3_数数字_UVa1225 P57_习题3-4_周期串_UVa455 P59_习题3-9_子序列_UVa10340 P57_习题3-1_得分_UVa1585 给出一个由O和X组成的串&#xff08;长度为1&#xff5e;80&a…

网络原理2 TCP协议

TCP协议 文章目录TCP协议TCP的特点TCP的基本特性确认应答机制超时重传机制丢包连接管理机制TCP建立连接---三次握手TCP断开连接---四次挥手滑动窗口机制丢包问题流量控制机制拥塞控制机制延迟应答机制捎带应答机制面向字节流问题TCP中的异常处理程序崩溃了正常关机突然断电关机…

在前端解决跨域

1、环境依赖 C:\Users\cyberzhaohyvm>node -v v14.17.3 C:\Users\cyberzhaohyvm>vue -V vue/cli 5.0.4 2、在项目所在目录&#xff0c;安装axios 进入项目所在目录&#xff1a; D:\01sourcecode\10Tutorial\08Vue\17-2022-12-28-v2\elementui-demo npm install axios …

Redis单线程为什么这么快?

Redis单线程为什么这么快&#xff1f; 第一章 Redis单线程为什么这么快 Redis深度剖析【第一章】Redis单线程为什么这么快&#xff1f;前言一、Redis为什么要使用单线程&#xff0c;而不是多线程&#xff1f;单线程的优势如果Redis使用多线程&#xff1a;既然多线程切换存在消…

【博学谷学习记录】大数据课程-学习第一周总结

Linux服务器 对于Linux操作系统来说&#xff0c;其本身是一个整体&#xff0c;包括Linux内核、系统库和系统程序&#xff0c;Linux内核是其最基础的部分&#xff0c;它实现了对硬件资源的管理&#xff0c;并且提供了使用这些硬件资源的通用接口。 自1991年发布Linux内核来&…

项目实战之旅游网(十四)项目部署-Docker

为了节约资源&#xff0c;在生产环境中我们更多的是使用Docker容器部署SpringBoot应用&#xff0c; 我们要用maven里的docker插件来生成镜像并且远程连接Docker&#xff0c; 开启远程docker服务&#xff1a; # 修改docker配置文件 vim /lib/systemd/system/docker.service 把…

简阅人体姿态估计深度学习方法-simpread-Human Pose Estimation Deep Learning Approach

What is Human Pose Estimation? Human Pose Estimation (HPE) is a way of identifying and classifying the joints in the human body Human Pose Estimation(HPR 人体姿态估计)是一个对人体关节进行识别和分类的方法。 Essentially it is a way to capture a set of co…

Good Bye 2022: 2023 is NEAR C. Koxia and Number Theory

原题链接&#xff1a;Problem - C - Codeforces 题意&#xff1a; 给定一个长度为n的数组&#xff0c;请问是否存在一个数 x &#xff0c;使得任意两个数 与满足 。若是输出 YES &#xff0c;反之输出 NO 。 思路&#xff1a; 我们可以发现一个规律&#xff1a; 规律&#…

本周大新闻|沙特PIF再投Magic Leap,周融资超5.1亿美元

本周大新闻&#xff0c;AR方面&#xff0c;OVER推出众包AR地图Map2Earn&#xff1b;AR房产平台homeAR推扫码看房功能&#xff1b;苹果智能指环专利公布&#xff0c;支持手势和触觉反馈。 VR方面&#xff0c;奇遇MIX正式发布&#xff1b;AjnaLens将发布新XR头显&#xff1b;Gen…

Cartesi 2022 年 12 月回顾

查看你不想错过的更新2022 年 12 月 31 日 &#xff0c;我们将继续保持高昂的建设斗志一直持续到2023年。我们在2022年年底前参加了两次编程马拉松&#xff0c; 并不是一次。我们将 Cartesi 的技术带给了ETH India 活动的2000 多名建设者&#xff0c;我们还与 SuperwomenDAO 合…

RabbitMQ消息确认

目录 1. 消息确认作用 2 开发示例 2.1 生产者确认 2.2 消费者确认 1. 消息确认作用 保证消息的可靠性主要依靠三种机制&#xff1a;一个是消息的持久化&#xff0c;一个是事务机制&#xff0c;一个就是消息的确认机制。 1&#xff09;消息持久化 消息持久化是将消息写入…

卷径计算详解(卷径通过卷绕的膜长和膜厚进行计算)

有关卷绕+张力控制可以参看专栏的系列文章,文章链接如下: 变频器简单张力控制(线缆收放卷应用)_RXXW_Dor的博客-CSDN博客_收放卷应用张力控制的开闭环算法,可以查看专栏的其它文章,链接地址如下:PLC张力控制(开环闭环算法分析)_RXXW_Dor的博客-CSDN博客。https://blo…

双向链表的双向冒泡排序、红白蓝砾石排序、算法设计4-5

&#xff08;PS&#xff1a;直接拿的友友zy的&#xff09; 一个不知名大学生&#xff0c;江湖人称菜狗 original author: jacky Li Email : 3435673055qq.com Time of completion&#xff1a;2023.1.1 Last edited: 2023.1.1 目录 &#xff08;PS&#xff1a;直接拿的友友zy的…

添加USB wifi驱动到RK3568

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录前言一、USB接口的wifi芯片二、使用步骤wireless tools 移植wireless tools 工具测试wpa_supplicant 移植openssl 移植libnl 库移植WIFI 联网测试总结前言 在日常开…