史上最细SQL实战系列:基础知识篇(补充)

这是我的史上最细SQL实战系列的第一篇文章:基础知识篇的补充篇。本系列文章核心不在于总结Mysql相关的八股(Mysql超全八股可见此文:Mysql超全八股笔记贴),本系列旨在:1.快速掌握sql知识,会写面试时常见的sql题目;2.了解在实际工作中需要注意的超多数据库和表设计相关的知识和坑点。

本系列文章分为3个部分:1基础知识篇;2sql笔试篇;3公司级数据库与表设计相关知识与坑点总结。

另外:

想要学习Java冲实习或冲春招的,我能助你一臂之力,我之前整理了高质量可速成的魔改外卖项目话术和7000字轮子项目话术,还有超全超精品八股大全专栏,怎么写简历,怎么包装实习经历,怎么0基础速成冲春招和实习等等等等精品帖子,大家可以去看看我的精品文章汇总帖子:https://www.nowcoder.com/discuss/721704696242536448?sourceSSR=users

我的八股大全、算法、项目话术全专栏(20w人学习,超千人订阅,牛客最受欢迎最高质量java八股专栏,内容包含: 1.八股大全:多一句没有少一句不行的最精简八股整理,完全可以应付校招社招的八股拷打! 2.速成项目话术:目前有魔改苍穹外卖项目话术(额外扩展了很多技术亮点),能速成拿去面试,后面会更新魔改黑马点评、商城项目等等热门高质量项目话术 3.智力题超详细题解汇总; 4.面试时非技术问题话术整理,绝对震惊面试官一年; 5.算法lc hot100全题系列题解:绝对通俗易懂快速冲刺秋招专栏

---------------------------------------------------------------------

1. 窗口函数

窗口函数,也叫OLAP函数(Online Anallytical Processing,联机分析处理),可以对数据库数据进行实时分析处理。窗口函数的基本语法如下:

<窗口函数> over ([partition by <用于分组的列名>]
                order by <用于排序的列名>)

中括号里内容可以省略

那么语法中的<窗口函数>都有哪些呢?<窗口函数>的位置,可以放以下两种函数:

1、 专用窗口函数,包括后面要讲到的rank, dense_rank, row_number等专用窗口函数。

2、 聚合函数,如sum. avg, count, max, min等

因为窗口函数是对where或者group by子句处理后的结果进行操作,所以窗口函数原则上只能写在select子句中

例如如果我们想在每个班级内按成绩排名,得到下面的结果。

以班级“1”为例,这个班级的成绩“95”排在第1位,这个班级的“83”排在第4位。上面这个结果确实按我们的要求在每个班级内,按成绩排名了。得到上面结果的sql语句代码如下:

select *,
   rank() over (partition by 班级
                 order by 成绩 desc) as ranking
from 班级表

我们来解释下这个sql语句里的select子句。rank是排序的函数。要求是“每个班级内按成绩排名”,这句话可以分为两部分:

1)每个班级内:按班级分组 - partition by用来对表分组。在这个例子中,所以我们指定了按“班级”分组(partition by 班级)

2)按成绩排名:order by子句的功能是对分组后的结果进行排序,默认是按照升序(asc)排列。在本例中(order by 成绩 desc)是按成绩这一列排序,加了desc关键词表示降序排列。

窗口函数的作用

窗口函数具备了我们之前学过的group by子句分组的功能和order by子句排序的功能。那么,为什么还要用窗口函数呢?

这是因为,group by分组汇总后改变了表的行数,一行只有一个类别。而partiition by和rank函数不会减少原表中的行数。例如下面统计每个班级的人数。

专用窗口函数有哪些?

专用窗口函数rank, dense_rank, row_number

举例:

select *,
   rank() over (order by 成绩 desc) as ranking,
   dense_rank() over (order by 成绩 desc) as dese_rank,
   row_number() over (order by 成绩 desc) as row_num
from 班级表

从上面的结果可以看出:

(1)rank函数:这个例子中是5位,5位,5位,8位,也就是如果有并列名次的行,会占用下一名次的位置。比如正常排名是1,2,3,4,但是现在前3名是并列的名次,结果是:1,1,1,4。

(2)dense_rank函数:这个例子中是5位,5位,5位,6位,也就是如果有并列名次的行,不占用下一名次的位置。比如正常排名是1,2,3,4,但是现在前3名是并列的名次,结果是:1,1,1,2。

(3)row_number函数:这个例子中是5位,6位,7位,8位,也就是不考虑并列名次的情况。比如前3名是并列的名次,排名是正常的1,2,3,4。

最后,需要强调的一点是:在上述的这三个专用窗口函数中,函数后面的括号不需要任何参数,保持()空着就可以

聚合函数作为窗口函数

聚和窗口函数和上面提到的专用窗口函数用法完全相同,只需要把聚合函数写在窗口函数的位置即可,但是函数后面括号里面不能为空,需要指定聚合的列名。我们来看一下窗口函数是聚合函数时,会出来什么结果:

select *,
   sum(成绩) over (order by 学号) as current_sum,
   avg(成绩) over (order by 学号) as current_avg,
   count(成绩) over (order by 学号) as current_count,
   max(成绩) over (order by 学号) as current_max,
   min(成绩) over (order by 学号) as current_min
from 班级表

有发现什么吗?我单独用sum举个例子:如上图,聚合函数sum在窗口函数中,是对自身记录、及位于自身记录以上的数据进行求和的结果。比如0004号,在使用sum窗口函数后的结果,是对0001,0002,0003,0004号的成绩求和,若是0005号,则结果是0001号~0005号成绩的求和,以此类推。

不仅是sum求和,平均、计数、最大最小值,也是同理,都是针对自身记录、以及自身记录之上的所有数据进行计算,现在再结合刚才得到的结果(下图),是不是理解起来容易多了?

比如0005号后面的聚合窗口函数结果是:学号0001~0005五人成绩的总和、平均、计数及最大最小值。如果想要知道所有人成绩的总和、平均等聚合结果,看最后一行即可。

**这样使用窗口函数有什么用呢?**聚合函数作为窗口函数,可以在每一行的数据里直观的看到,截止到本行数据,统计数据是多少(最大值、最小值等)。同时可以看出每一行数据,对整体统计数据的影响。

注意

1.因为窗口函数是对where或者group by子句处理后的结果进行操作,所以窗口函数原则上只能写在select子句中牢记是在执行完select之后,在所得结果集之上进行partition

2.partition子句可以省略,省略就是不指定分组,结果如下,只是按成绩由高到低进行了排序

select *,
   rank() over (order by 成绩 desc) as ranking
from 班级表

但是,这就失去了窗口函数的功能,所以一般不要这么使用。

SQL经典面试题:topN问题

工作中会经常遇到这样的业务问题:如何找到每个类别下用户点击最多的5个商品是什么?这类问题其实就是常见的:每组最大的N条记录(topN)。

1、题目:现有“成绩表”,记录了每个学生各科的成绩。

2、问题:查找每个学生成绩最高的2个科目。

3、解题思路:

(1)看到问题中要查**“每个”学生最高的成绩,当有“每个”出现的时候,就要想到是要分组**了。这里是“每个学生”,结合表的结构,是按学生“姓名”来分组。

(2)将表按学生姓名分组后,把成绩按降序排列,排在最前面的2个就是我们要找的“成绩最高的2个科目”。

(3)现在分组后,需要排序,又不减少原表的行数,这种功能自然想到是窗口函数。

(4)使用哪个专用窗口函数?为了不受并列成绩的影响,使用row_number专用窗口函数

错误思路:

select *, 
      row_number() over (partition by 姓名
                   order by 成绩 desc) as ranking
from 成绩表
where ranking <=2

这样写,sql会报错,为什么呢?

要牢记sql的书写顺序和运行顺序。在运行顺序中,select字句是最后被运行的。

当明白了运行顺序以后,就知道错误的原因了:运行到”where ranking > 2”的时候,因为select字句还没有被执行,因此select中的“ranking”列还没有出现,从而导致报错。

正确解法:

select *
from (
   select *, 
          row_number() over (partition by 姓名
                       order by 成绩 desc) as ranking
   from 成绩表) as a
where ranking <=2

2.CTE

CTE是Common Table Expressions通用表表达式,它允许我们创建一个临时的命名结果集,可以在SQL语句内部引用。CTE通常由WITH关键字定义,并且可以在SQL语句中多次使用。使用CTE可以将复杂的查询分解为可读性更强的部分,提高SQL语句的可维护性。

CTE由两部分组成:名称和查询。名称用于引用CTE,并在同一SQL语句中多次使用。查询是一个普通的SELECT语句,用于定义CTE的内容。

CTE 可以理解成一个可以复用的子查询,当然跟子查询还是有点区别的,CTE 可以引用其他 CTE,但子查询不能引用其他子查询。

基础语法:

WITH cte_name (column1, column2, ...) AS (
    -- CTE的查询定义
    SELECT expression1, expression2, ...
    FROM table_name
    WHERE condition
)
-- 主查询,引用CTE
SELECT * FROM cte_na

剩余60%内容,订阅专栏后可继续查看/也可单篇购买

内容包含: 1.八股大全:多一句没有少一句不行的最精简八股整理,完全可以应付校招八股拷打! 2.速成项目话术:目前有魔改苍穹外卖项目话术(额外扩展了很多技术亮点),能速成拿去面试,后面会更新魔改黑马点评、商城项目等等热门高质量项目话术 3.智力题超详细题解汇总; 4.面试时非技术问题话术整理,绝对震惊面试官一年; 5.算法lc hot100全题系列题解:绝对通俗易懂。 会慢慢涨价,欢迎订阅!

全部评论

相关推荐

1.&nbsp;自我介绍(先做一个自我介绍)2.&nbsp;回顾计算机相关基础知识时有没有什么收获?3.&nbsp;怎么查看Docker日志?4.&nbsp;Linux系统上看日志文件用什么命令?正在生成的日志和要截取的日志分别用什么参数?5.&nbsp;日志命令中-&nbsp;f和其他参数的区别是什么?-&nbsp;f是干什么的?不带-&nbsp;f呢?6.&nbsp;用三两句话简单介绍自己做的事情和擅长的技能。7.&nbsp;参考百度网盘做AI云盘时,怎么推测它的功能和实现?举具体例子(如文件目录拉取)说明怎么推测、怎么实现,以及如何判断推测对错。8.&nbsp;文件存储和目录存储的区别是什么?它们的数据结构是什么样子的?9.&nbsp;如何通过一个文件回到它的上一层目录?回到上面三层呢?若要实现点击地址行直接跳转,准备怎么设计?10.&nbsp;把一个文件/目录从一个目录移到另一个目录,存储里要改变哪些东西?移动目录时怎么做?11.&nbsp;删除目录时用了什么操作?12.&nbsp;目录下文件特别多,递归去做移动/删除会有什么问题?怎么解决?13.&nbsp;短链是怎么做的?(是不是复现别人成型的东西)14.&nbsp;长链怎么转成短链?长链和短链的对应关系是什么?15.&nbsp;62取模得到的是什么?哈希取模会不会有问题?16.&nbsp;短链算法能支持多少范围的链接?17.&nbsp;作为短链平台,要支持很多公司生成短链,且要求短链短、支持量足够大,怎么设计短链算法?18.&nbsp;Java中HashMap是怎么实现的?1.7和1.8有什么区别?19.&nbsp;HashMap为什么既要链表又要红黑树?两者性质有什么差别?20.&nbsp;什么是平衡树?红黑树是怎么维持平衡的?需要旋转吗?21.&nbsp;除了红黑树,还了解哪些平衡树?22.&nbsp;Java中JVM内存分配时,新生代和老年代的担保机制具体是什么?23.&nbsp;GVM的内存结构是什么样子的?新生代、老年代、元空间分别存什么内容,数据怎么整理流转?24.&nbsp;除了复制算法,还有哪些垃圾回收算法?它们有什么区别?25.&nbsp;分代收集算法是什么?26.&nbsp;MySQL的事务隔离级别有哪些?分别是什么意思?27.&nbsp;事务隔离级别中,无锁的实现方式是什么?MVCC了解吗?怎么实现的?28.&nbsp;MVCC能解决幻读问题吗?为什么?29.&nbsp;Redis中用了什么数据结构?Redis的字符串数据结构是怎么实现的?30.&nbsp;给定旋转有序数组(如1356789→7891356),设计查找算法(如查找5、8、2)。31.&nbsp;设计的查找算法和二分查找有什么区别?32.&nbsp;给定二叉树的两个节点,怎么找它们的最低公共祖先?33.&nbsp;给定二叉树的三个节点,怎么找最低公共祖先?34.&nbsp;给定二叉树的四个、五个节点,怎么找最低公共祖先?35.&nbsp;给定多个段(段内有序,合并时相同k的item保留value最大的),设计合并算法,说明思路。36.&nbsp;有没有什么问题想问面试官?
点赞 评论 收藏
分享
评论
6
18
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务