SQL高级语句部分知识点笔记

高级语句和前一篇中基础语句的区别在于,高级语句使用的场景不太相同,需要对基础语句进行组合性使用

窗口函数

标准语法: over partition by 字段名  order by 字段名 asc | desc

(注意 partition by 和 order by 二者之间没有 进行隔开,切忌加上 逗号)

语法讲解:over()中两个子句为可选项,partition by指定分区依据,order by 指定排序依据

窗口函数的作用:

理解起来好比,我首先在第一个网页中进行一些操作得到结果,然后再另开一个新的网页,对刚刚的数据进行处理得到一些结果,然后再将这个新开的网页中得到的结果 匹配回第一个网页中。

更加生动的例子就是:在计算数学题时,在试卷的空白处写好了解题过程,然后 在草稿纸中进行计算得到最终结果,最后再将结果 写到试卷中

在这个过程中,草稿纸的作用就是  窗口函数的作用

如何理解窗口函数的语法结构呢?为什么over()要放在函数后面?该如何理解?

答:以rank() over()为例,over后面的相当于是草稿,也即是窗口函数,在over()里面将数据进行分区和排序,就好比是在over()里面做草稿,然后再将草稿中的结果 返回。返回的方式就是 rank()。理解起来就像,over()将草稿打好,然后根据草稿的推理,直接将答案写到试卷上,而这个答案的获取 就是 rank()

 检测到窗口函数以后,返回时是返回到having语句之后,order by和limit可以引用窗口函数的结果,而having之前的语句则不行

排序窗口函数:

rank() over():跳跃式排序。比如现在有成绩 100 100 99 98,那么排名为 1,1,3,4

dense_rank() over() :并列连续型排序。有成绩 100 100 99 98,那么排名为 1,1,2,3

row_number() over():连续型排序。有成绩 100 100 99 98,那么排名为 1,2,3,4

当数值没有重复时,三个函数作用相同

例题:

查询2017年选区为‘$14000024’的所有候选人所在团体和其选票数(votes)、还有候选人得票数在选区内对应的排名,结果按照团队party排序

select party, votes,
rank()over(order by votes desc)
from ge
where area = '$14000024' and yr = 2017

偏移分析函数:

lag(字段名, 偏移量 ( 默认值 )  ) over()

作用:将某个字段向后延迟多少行  lag这个英文单词本身的意思是:滞后; 落后于

所以说,这个函数就相当于是将 某个字段 在某行 延迟 多少个单位

而lead函数,就是向下偏移

lead(字段名,偏移量 ( 默认值) ) over()

例题:

已知有一个疫情的表格,有国家、日期、每日累计确诊病例、累计治愈、累计死亡。

现要求查询法国和德国1月每天新增确诊人数,最后显示国家名,标准日期(2020-01-27),当天截止时间累计确诊人数,昨天截止时间累计确诊人数,每天新增确诊人数,按照截至时间排序。如何处理?

思路:

用今天的累计确诊  减去  昨天的累计确诊 便能够得到  今日新增确诊

那么如何用代码实现?

select country,date
confirmed 累计确诊,
lag(confirmed, 1) over(partition by country order by date asc) 昨日累计确诊,
confirmed - lag(confirmed, 1) over(partition by country, order by date asc) 新增确诊
from covid
where country in ('France','Germany') and month(date) = 1
order by date

例题:

查询意大利每周新增确诊数,最后显示国家名,标准日期,每周新增人数,按照截止时间排序

select country 国家名,
date_format(whn, '%Y-%m-%d') 标准日期,
confirmed - lag(confirmed.1)over(order by date) 每周新增人数
from covid
where country = 'Italy' and weekday(whn) = 0
order by whn

窗口函数注意事项:

1.窗口函数只能写在select子句中

2.窗口函数中的 partition by 子句可以指定数据的分区,作用上和group by基本一致,但是区别在于:partition by 并不会去重

3.窗口函数中没有 partition by 子句时,说明此时不对数据进行分区,所有的数据组成一个区

4.排序窗口函数中 order by 子句是必选项,窗口函数中 order by子句在分区内,一句指定字段和排序方法对数据进行排序

5.rank()  dense_rank()  row_number()  这三个排序窗口函数的异同之处。

主知识九:表连接

知识点引入:

一共有三种连接方法:内连接、左连接、右连接

左右连接其实就是在内连接的基础之上进行一个筛选

内连接语法:

select 字段名

from 表1 (inner) join 表2 on 表1.字段名 = 表2.字段名

注意:一般连接都是默认 内连接,所以 单纯写 join  就 默认是 inner join

逻辑是:表1中的字母逐个和表2中对应的字母连接,得到新的行。例如表1中的A 1,先和表2中的A全部连接完之后,再到表1中的A 2和表2中的A 逐个连接。

若出现像表1中F在表2中没有F对应的这种情况,那么结果便会得到空值 null

left join左连接:

左连接强调的是:左边表格里面的值 一个都不能少,右边的表格要与左边的表格相匹配。

如果左边的表格里,匹配的字段是空值,那么也会被剔除掉

right join右连接:

右连接强调的是:右边表格里面的值 一个都不能少,左边的表格要与右边的表格相匹配。

如果右边的表格里,匹配的字段是空值,那么也会被剔除掉

有如下表格:有三个表格 game、goal、eteam

game包含id、mdate(比赛日期)、stadium()、team1和team2;goal包含matchid、teamid、player、gtime(进球时间);team包括id(队伍编号)、teamname(队名)、coach(教练)

例题:

查询有球员名叫Mario进球的队伍1和队伍2以及球员姓名

select team1, team2, player
from game join goal on game.id = goal.matchid
where player = 'Mario'

表连接时的一些细节处理:

在from语句中,也可以给表格起别名,方法跟select中起别名一样,目的在于方便表连接时能够简便些

例题:

查询每场比赛、每个球队的得分情况,并返回mdate team1 score1 team2 score2

主知识点十:子查询

作用理解:相当于是 先进行查询,得到一个查询结果,然后再将该查询结果作为条件 再进行查询

知识点汇总:

子查询是可以自己正常独立运行的语句,作用就在于:将子查询的结果(结果并不仅仅指一个数值,也可以是指一个表格)作为条件 或者是 from语句查询的表格  再进行查询

1.比如说,可以在where 条件的后面运用到 子查询

2.在from语句中运用子查询得到的 表 ,作为查询的表格来源

例题:

查询2017年所有在爱丁堡的选区当选议员 所在选区及其团队。已知爱丁堡选区编号为S14000021至S14000021,当选议员即各选取得票数最高的候选人。

select constituency, party, votes
from (
     子查询语句,返回一个表格
as rk
where rk.position = 1
但是有一点必须得注意! from 子查询必须得给别名!而且,在后面选择相关字段时格式上也必须得发生改变!

这样处理的原因是:如果没有别名,那么数据库将无法识别,不知道查询的字段来自于哪个表格

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值