深度思考面试常考sql题

1 推荐工具

在线运行SQL

2 阿里一面

3 百度一面

4 一道百度校招二面sql题

力推一个在线运行sql的网站:https://www.json.cn/runcode/run_sql/

有一张学生表stu,包含sid, std_name,course_name,score等几个字段,数据如下,要求查询出每门课程排名前三名的学生记录,

/*sid, std_name,course_name,score1 小明 语文 902 小明 语文 923 小明 语文 934 小明 语文 945 小泓 数学 926 小泓 英文 937 小刚 科学 94语文 94-93-92数学*/CREATE TABLE stu (sid int,std_name varchar(255),course_name varchar(255),score int
);INSERT INTO stu VALUES (1, 'Tom', 'Chinese', 90);
INSERT INTO stu VALUES (2, 'Tom2', 'Chinese', 91);
INSERT INTO stu VALUES (3, 'Tom3', 'Chinese', 92);
INSERT INTO stu VALUES (4, 'Tom4', 'Chinese', 93);INSERT INTO stu VALUES (5, 'Tom5', 'English', 93);
INSERT INTO stu VALUES (6, 'Tom6', 'English', 94);INSERT INTO stu VALUES (7, 'Tom7', 'Math', 91);

4.1 方法一(我写的,面试官不是很认可):使用group_concat函数(缺点是只能限制拼接后的最长字符串,不能限制拼接的元素数量)

【SQL学习笔记一】Group_Concat()

// 先堆
// select course_name,group_concat(std_name,"-"),group_concat(score, "-") from (select * from stu order by score desc) as tmp group by course_name// 协会站点,入会当会员//表
/*学生表、部门表、学生-部门表、新闻表*/// (select * from stu order by course_name desc, score desc) as tmp

4.2 方法二:使用子查询

SELECT s1.sid, s1.std_name, s1.course_name, s1.score
FROM stu s1
WHERE (SELECT COUNT(DISTINCT s2.score) FROM stu s2 WHERE s2.course_name = s1.course_name AND s2.score > s1.score
) < 3
ORDER BY s1.course_name, s1.score DESC;

4.2.1 sql语句解析

当然可以。这是一种子查询的方法,它使用自连接来获取每个课程的前三名学生的成绩。以下是对这个查询的详细解释:

  1. 主查询

    主查询是对stu表的查询,它选取了学生的sidstd_namecourse_namescore

    SELECT s1.sid, s1.std_name, s1.course_name, s1.score
    FROM stu s1
    
  2. 子查询

    对于主查询中的每个学生(或记录),都会运行一次子查询。子查询的目的是计算当前学生的成绩在其课程中的排名。

    SELECT COUNT(DISTINCT s2.score) 
    FROM stu s2 
    WHERE s2.course_name = s1.course_name AND s2.score > s1.score
    

    这里,我们正在数那些在同一课程中但成绩高于当前学生(s1)的其他学生(s2)的数量。因此,如果子查询的结果为0,这意味着当前学生是这门课的第一名;如果结果为1,这意味着当前学生是第二名,以此类推。

  3. WHERE条件

    WHERE (...
    ) < 3
    

    该条件确保我们只选取排名在前三名的学生。只有当子查询的结果为0、1或2时(即该学生的成绩在其课程中排名前三),该学生的记录才会被选中。

  4. ORDER BY子句

    ORDER BY s1.course_name, s1.score DESC;
    

    这个子句首先按课程名称对结果进行排序,然后在每个课程内部,按学生的成绩降序排列。

简单来说,这个查询为每个学生计算他们在自己的课程中的成绩排名,然后选取排名在前三名的学生。

4.2.2 子查询的使用位置

子查询并不仅限于WHERE子句中。它们可以出现在以下位置:

  • SELECT子句中,作为派生列。
  • FROM子句中,作为派生表。
  • WHERE子句中,与操作符(如IN, EXISTS)一起使用。
  • HAVING子句中。
  • JOIN操作中。

4.2.3 子查询、EXISTSIN的关系

我的笔记(Sql语句中IN和exists的区别及应用)

  • 子查询与IN: 当你需要比较一个值是否在一组值中时,可以使用子查询与IN结合。

    SELECT employee_id FROM employees WHERE department_id IN (SELECT department_id FROM departments WHERE location = 'New York');
  • 子查询与EXISTS: 当你需要检查一个子集是否存在时,可以使用EXISTS。它是一个半关联操作,通常与关联条件结合使用。

    SELECT customer_id FROM customers c WHERE EXISTS (SELECT 1 FROM orders o WHERE o.customer_id = c.customer_id);

    EXISTS通常更高效,因为它在找到第一个匹配项后就会停止搜索。

N 和 EXISTS 的区别及应用场景

  • 区别

    • 如你所说,INEXISTS关键字在执行查询时使用的策略是不同的。具体执行策略和数据库优化器的实现有关,但大致的概念是:

      • IN子查询首先被执行,然后将得到的结果集返回给主查询,之后主查询进行过滤。
      • 对于EXISTS子查询,通常外层的每一行数据都会检查子查询是否存在满足条件的记录。
  • 应用场景

    • IN更适合子查询返回的结果集小,而主查询的数据集大并且具有适当的索引的场景。
    • EXISTS在外部查询的数据集较小而子查询的数据集较大并且具有适当索引的情况下表现得更好。
  • 关于效率

    • 这两者之间没有固定的“哪个总是更快”的规则,它取决于数据的特性和查询的具体情境。通常,最佳的做法是编写两种查询并检查执行计划或实际执行时间。

4.3 方法三:使用窗口函数

如上文中的ROW_NUMBER()方法(能够保证强排名,如果两个人并列第三,只返回其中number号靠前的那一个)。除此之外,你还可以使用RANK()【并列的前三名都会返回】或DENSE_RANK()

WITH RankedScores AS (SELECT sid,std_name,course_name,score,ROW_NUMBER() OVER(PARTITION BY course_name ORDER BY score DESC) AS rankingFROM stu
)
SELECT sid,std_name,course_name,score
FROM RankedScores
WHERE ranking <= 3;

4.3.1 什么是窗口函数

窗口函数是SQL的高级功能,允许在结果集的一组行上执行计算,这组行与当前行有某种关系。换句话说,窗口函数为当前行定义了一个"窗口",并根据这个窗口计算值。这些函数与普通的聚合函数(如SUM、AVG)不同,因为窗口函数不会减少结果集的行数;它们为每一行提供计算结果。

窗口函数通常与OVER子句一起使用,OVER子句定义了为每一行计算函数值的窗口。

4.3.2 解释 WITH RankedScores AS ...

这是一个常用的SQL特性,叫做"公共表表达式" (Common Table Expression, 简称CTE)。CTE为查询提供了一种定义临时结果集的方式,这个结果集只存在查询的执行期间,并且它可以在之后的查询中引用。

在给定的查询中,CTE RankedScoresstu表中的每个学生按照course_name进行分区,并为每个学生计算一个名次ranking,名次基于他们的score从高到低排序。

解释CTE中的查询:

  • RANK(): 是一个窗口函数,为每一行提供一个名次。
  • OVER(PARTITION BY course_name ORDER BY score DESC): 定义了一个窗口。这里,PARTITION BY course_name意味着为每门课程单独计算名次。ORDER BY score DESC意味着名次是基于分数从高到低排序的。
  • AS ranking: 将窗口函数的结果命名为ranking

所以,这个CTE为每位学生提供了一个名次,基于他们在特定课程中的分数。之后的主查询从这个CTE中选择名次在前三的学生。

4.3.3 常见的窗口函数

  • ROW_NUMBER(): 对每个窗口中的行进行编号。
  • RANK(): 在窗口内为行分配一个唯一的排名,排名并列的情况下会留下空缺。
  • DENSE_RANK(): 与RANK()相似,但不会在排名中留下空缺。
  • NTILE(n): 将窗口内的行分为n个大致相等的部分,并为每部分的行提供一个编号。
  • LAG(column, n): 返回当前行前n行的值。
  • LEAD(column, n): 返回当前行后n行的值。
  • FIRST_VALUE(column): 返回窗口内的第一个值。
  • LAST_VALUE(column): 返回窗口内的最后一个值。
  • SUM(column), AVG(column), MIN(column), MAX(column): 在窗口内计算总和、平均值、最小值和最大值。

4.3.4 举一个例子告诉rank(), dense_rank()和row_number()等窗口函数的区别

1 rank()
WITH RankedScores AS (SELECT sid,std_name,course_name,score,RANK() OVER(PARTITION BY course_name ORDER BY score DESC) AS rankingFROM stu
)
SELECT sid,std_name,course_name,score,ranking
FROM RankedScores
WHERE ranking <= 3;

查询结果:

3|Tom3|Chinese|93|1
4|Tom4|Chinese|93|1
2|Tom2|Chinese|91|3
6|Tom6|English|94|1
5|Tom5|English|93|2
7|Tom7|Math|91|1
2 dense_rank()
  
WITH RankedScores AS (SELECT sid,std_name,course_name,score,DENSE_RANK() OVER(PARTITION BY course_name ORDER BY score DESC) AS rankingFROM stu
)
SELECT sid,std_name,course_name,score,ranking
FROM RankedScores
WHERE ranking <= 3;

查询结果:

3|Tom3|Chinese|93|1
4|Tom4|Chinese|93|1
2|Tom2|Chinese|91|2
1|Tom|Chinese|90|3
6|Tom6|English|94|1
5|Tom5|English|93|2
7|Tom7|Math|91|1
3 ROW_NUMBER()

WITH RankedScores AS (SELECT sid,std_name,course_name,score,ROW_NUMBER() OVER(PARTITION BY course_name ORDER BY score DESC) AS rankingFROM stu
)
SELECT sid,std_name,course_name,score,ranking
FROM RankedScores
WHERE ranking <= 3;
3|Tom3|Chinese|93|1
4|Tom4|Chinese|93|2
2|Tom2|Chinese|91|3
6|Tom6|English|94|1
5|Tom5|English|93|2
7|Tom7|Math|91|1

4.3.5 `SUM(column)`, `AVG(column)`, `MIN(column)`, `MAX(column)`这些函数是对窗口内所有的记录生效的吧 2 `LAG(column, n)`, `LEAD(column, n)`和`NTILE(n)`,分别给几个demo

  1. 是的,SUM(column), AVG(column), MIN(column), MAX(column)这些函数都是对窗口内的所有记录生效的,而具体的窗口范围由PARTITION BYORDER BY决定。

  2. DEMO:

    • LAG(column, n): 这个函数用于返回当前行上方n行的值。如果没有这么多行,它将返回NULL。

      SELECT column,LAG(column, 1) OVER (ORDER BY some_column) AS prev_value
      FROM table_name;
      

      这将给出当前行和前一行的值。

    • LEAD(column, n): 与LAG类似,但返回当前行下方n行的值。

      SELECT column,LEAD(column, 1) OVER (ORDER BY some_column) AS next_value
      FROM table_name;
      

      这将给出当前行和下一行的值。

    • NTILE(n): 这个函数用于将结果集分成n个大致相等的部分,并为每部分的行分配一个编号。

      SELECTcolumn,NTILE(4) OVER (ORDER BY some_column) AS quartile
      FROM table_name;
      

      这将为每行分配一个从1到4的值,表示它在哪个四分位数中。

请注意,这些DEMO只是基本用法的示例,实际应用可能会更复杂,取决于具体的数据和需求。

4.4 方法四:在某些数据库(如MySQL)中,可以使用用户定义的变量来计算每个课程的排名。

SET @ranking = 0;
SET @prev_course = '';
SELECT sid, std_name, course_name, score
FROM (SELECT sid, std_name, course_name, score,@ranking := IF(@prev_course = course_name, @ranking + 1, 1) AS ranking,@prev_course := course_nameFROM stuORDER BY course_name, score DESC
) AS RankedScores
WHERE ranking <= 3;

4.4.1 解释一下用法

这个查询是使用MySQL的用户定义变量来实现学生的成绩排名功能。它的目标是为每门课程中的学生按分数降序排名,并只选择排名前三的学生。

我来逐步解释这个查询:

1. 设置用户定义变量
SET @ranking = 0;
SET @prev_course = '';

这里,我们初始化两个用户定义变量:

  • @ranking:用于存储当前学生的排名。
  • @prev_course:用于存储上一行的课程名,这样我们可以检查当前行的课程是否与上一行的课程相同。
2. 子查询
SELECT sid, std_name, course_name, score,@ranking := IF(@prev_course = course_name, @ranking + 1, 1) AS ranking,@prev_course := course_name
FROM stu
ORDER BY course_name, score DESC

这个子查询做了以下几件事:

  • 首先,它对结果集进行排序,使得同一门课程的学生按其分数降序排列。
  • 使用IF函数来检查当前行的课程名是否与前一行的课程名相同。如果相同,@ranking加1;如果不同,@ranking重置为1。
  • 更新@prev_course为当前行的课程名。
3. 主查询
SELECT sid, std_name, course_name, score
FROM ... AS RankedScores
WHERE ranking <= 3;

这个主查询简单地从子查询的结果中选择排名前三的学生记录。

总的来说,这个查询使用MySQL的用户定义变量为每门课程的学生分数进行排名,并只选择排名前三的记录。

5 MySQL 8的新特性:

MySQL 8的新特性

MySQL 8在2018年发布,并带来了许多新的特性和改进:

  • 数据字典事务性:以前,MySQL中的元数据存储在多个文件和非事务性表中。在MySQL 8.0中,有了一个新的数据字典,所有的元数据都存储在单独的事务性表中。

  • 增强的UTF-8支持:默认的字符集从latin1更改为utf8mb4,支持更多的字符集,如Emoji、各种符号等。

  • 窗口函数:这为SQL在MySQL中提供了标准的窗口函数,如ROW_NUMBER(), LEAD(), LAG(),等等。

  • 公共表表达式 (Common Table Expressions, CTEs):通过使用WITH子句,MySQL 8.0开始支持CTEs。

  • 原子DDL语句:DDL操作(如创建、更改、删除表或索引)现在是原子的,并完全支持事务。

  • 角色支持:MySQL 8.0添加了对SQL角色的原生支持。

  • 性能模式:一个新的性能查询工具,用于监控服务器和查询的性能。

  • JSON增强:对JSON数据类型的增强和改进。

  • 优化器改进:查询执行计划的改进、直方图的引入等。

  • 其他安全、复制和性能的改进

4.5 类似于这种难度的sql,你还能再多出几个嘛

当然可以,这里是一些类似难度的SQL题目以及它们的背景描述:

  1. 获取每个员工的工资排名:
    假设您有一个employees表格,其中包含id, name, 和salary字段。您需要编写一个SQL查询来获取每个员工的工资排名,不考虑并列情况。

  2. 查找顾客购买最多商品的日期:
    假设您有一个orders表格,其中包含id, customer_id, product_id, 和order_date字段。您的任务是确定哪一天有最多的不同客户下单。

  3. 查找没有订单的顾客:
    假设您有两个表格,customersorders。您需要列出那些至今还没有下单的客户。

  4. 获取每个产品的总销售额:
    您有一个products表和一个sales表。您需要为每种产品计算总销售额。

  5. 查找连续三天访问网站的用户:
    您有一个user_visits表,其中包含user_idvisit_date字段。您的任务是找出连续三天都访问网站的用户。

  6. 查找上一个月的最佳销售员:
    您有一个sales表和一个employees表。您需要找出上个月销售额最高的员工。

这只是几个SQL难题的例子,实际上有无数的可能性和场景,您可以根据具体的数据模型和需求来定制。

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

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

相关文章

在 centos7 上安装Docker

1、检查linux内核 Docker 运行在 CentOS 7 上&#xff0c;要求系统为64位、系统内核版本为 3.10 以上。 Docker 运行在 CentOS-6.5 或更高的版本的 CentOS 上&#xff0c;要求系统为64位、系统内核版本为 2.6.32-431 或者更高版本。 uname -r 2、使用 root 权限登录 Centos…

Springboot 集成 Redis集群配置公网IP连接报私网IP连接失败问题

1、问题&#xff1a;在Springboot 集成 Redis集群配置公网IP连接报私网IP连接失败&#xff0c;一直报私有IP连接失败 14 14:57:49.180 WARN 22012 --- [ioEventLoop-6-4] i.l.c.c.topology.ClusterTopologyRefresh : Unable to connect to [192.168.0.19:6384]: connection …

vue、uniapp实现组件动态切换

在Vue中&#xff0c;通过使用动态组件&#xff0c;我们可以实现组件的动态切换&#xff0c;从而达到页面的动态展示效果。 vue 中 component组件 is属性 功能描述 例如&#xff1a;有多个tabs标签&#xff0c;如&#xff1a;推荐、热点、视频等。用户点击标签就会切换到对应组…

docker应用记录总结

一、前言 docker这类部署工具&#xff0c;久而久之不使用非常容易忘记&#xff0c;甚至连操作命令都容易忘记。网上也有比较全的docker使用教程。这里做一个记录总结&#xff0c;纯属是温故知新。 二、docker部署应用 1、docker印象 docker首先让我想到的是是虚拟化技术&…

使用Python构造VARIMA模型

简介 VARMA(p,q)结合了VAR和VMA模型&#xff0c;其中p是向量自回归(VAR)模型的滞后期数&#xff0c;q是VMA模型的移动平均的阶数。 VARMA是ARMA的推广&#xff0c;它将ARMA模型扩展到多个时间序列变量的情况&#xff0c;通过VAR和VMA的线性组合来描述多个时间序列变量之间的联…

踩雷react-useRef钩子函数

今天测试提了一个bug&#xff0c;之前做的有个需求&#xff0c;在触发事件发起请求后&#xff0c;成功响应返回的新的数据没有第一时间渲染到网页上。 方法也都成功更新了数据&#xff0c;就是渲染会慢1-2分钟&#xff0c;排错排了老半天&#xff0c;最后找到了原因。 一般情…

系统架构设计:18 论基于DSSA的软件架构设计与应用

目录 一 特定领域软件架构DSSA 1 DSSA 2 DSSA的基本活动和产物 (1)DSSA的基本活动和产物

node.js知识系列(4)-每天了解一点

目录 11. 异步文件操作文件读取文件写入 12. 包管理器&#xff08;npm&#xff09;13. 子进程14. 事件发射器&#xff08;EventEmitter&#xff09;15. 异步编程和回调16. Node.js 集成测试工具和框架17. Express.js 中间件的 HTTP 请求流程18. 文件上传和验证19. Express.js 中…

SpringBoot和Hibernate——如何提高数据库性能

摘要&#xff1a;本文由葡萄城技术团队发布。转载请注明出处&#xff1a;葡萄城官网&#xff0c;葡萄城为开发者提供专业的开发工具、解决方案和服务&#xff0c;赋能开发者。 前言 在软件开发领域&#xff0c;性能是重中之重。无论您是构建小型 Web 应用程序还是大型企业系统…

单目标应用:遗传算法(Genetic Algorithm,GA)求解微电网优化MATLAB

一、微网系统运行优化模型 微电网优化模型介绍&#xff1a; 微电网多目标优化调度模型简介_IT猿手的博客-CSDN博客 二、遗传算法GA 遗传算法&#xff08;Genetic Algorithm&#xff0c;GA&#xff09;起源于对生物系统所进行的计算机模拟研究&#xff0c;是一种随机全局搜索…

【Java 进阶篇】JavaScript 数据类型详解

JavaScript是一种弱类型脚本语言&#xff0c;具有动态类型。这意味着JavaScript中的变量可以容纳不同类型的数据&#xff0c;并且它们的类型可以在运行时更改。在本文中&#xff0c;我们将深入探讨JavaScript中的数据类型&#xff0c;包括原始数据类型和引用数据类型&#xff0…

安科瑞ARB5系列弧光保护装置,智能电弧光保护,保障用电安全

安科瑞虞佳豪壹捌柒陆壹伍玖玖零玖叁 什么是弧光 电弧是放电过程中发生的一种现象&#xff0c;当两点之间的电压超过其工频绝缘强度极限时就会发生。当适当的条件出现时&#xff0c;一个携带着电流的等离子产生&#xff0c;直到电源侧的保护设备断开才会消失。空气在通常条件…

【ARM CoreLink 系列 6 -- DMC-400控制器简介】

文章目录 1.1 DMC-400 简介1.1.1 DFI&#xff08;DDR PHY Interface&#xff09;1.1.2 DFI 接口组1.1.3 DMC-400 兼容协议1.1.4 DMC-400 特性1.1.5 DMC-400 Interface 1.1 DMC-400 简介 DMC-400是一个由ARM开发、测试和授权的动态内存控制器&#xff0c;同时 DMC-400也是一个符…

git 回滚到指定版本

第一步&#xff1a;找到指定的需要回滚的版本的版本号 项目终端输入命令git log --oneline 第二步&#xff1a;使用git命令回滚到指定的版本 git reset --hard 版本号 第三步&#xff1a;此时再推到远程仓库用git push 会报错&#xff0c;需要用git push -f强推上去才可以哦

Swagger-go学习笔记

目录 Swagger的作用背景Swagger介绍 Swagger的基本使用1. 使用步骤2. 添加注释3. 生成接口文档数据4. 引入gin-swagger5. 测试结果6. 使用Token Swagger-go的中文文档通用API信息API操作MIME类型参数类型数据类型 Swagger的作用 背景 在传统的前后端分离的项目中&#xff0c;…

vue3组件的通信方式

一、vue3组件通信方式 通信仓库地址:vue3_communication: 当前仓库为贾成豪老师使用组件通信案例 不管是vue2还是vue3,组件通信方式很重要,不管是项目还是面试都是经常用到的知识点。 比如:vue2组件通信方式 props:可以实现父子组件、子父组件、甚至兄弟组件通信 自定义事件:可…

C语言自定义类型_枚举联合(3)

目录 枚举 什么是枚举类型&#xff1f; 枚举的声明 枚举的定义 枚举的优点 枚举的使用 联合&#xff08;共用体&#xff09; 什么是联合呢&#xff1f; 联合类型的定义 联合的特点 联合使用 联合大小的计算 联合的应用 今天接着我们来结束自定义类型。&#x1f19…

Flink之Watermark源码解析

1. WaterMark源码分析 在Flink官网中介绍watermark和数据是异步处理的,通过分析源码得知这个说法不够准确或者说不够详细,这个异步处理要分为两种情况: watermark源头watermark下游 这两种情况的处理方式并不相同,在watermark的源头确实是异步处理的,但是在下游只是做的判断,这…

TensorFlow学习:在web前端如何使用Keras 模型

前言 在上篇文章 TensorFlow学习&#xff1a;使用官方模型进行图像分类、使用自己的数据对模型进行微调中我们学习了如何使用官方模型&#xff0c;以及使用自己的数据微调模型。 但是吧&#xff0c;代码一直是跑在Python里&#xff0c;而我本身是做前端开发的。我是很想让它在…

es elasticsearch 基础

es https://www.elastic.co/guide/en/elasticsearch/reference/6.8/getting-started.html 倒排索引&#xff1a; 正排–>从目录到文章内容 倒排–>内容到目录文章标题 if we dont need full text search ,we dont need to create 倒排 using text type 分词&#xff1a…