其实也没多高级,就是将之前一篇基础语句的组合使用。【视频学习:B站-戴戴戴师兄】
https://blog.youkuaiyun.com/weixin_61926490/article/details/135296938?spm=1001.2014.3001.5502
- SQL查询语句语法结构和运行顺序
- 语法结构:select--from--where--group by--having--order by--limit
- 运行顺序:from--where--group by--having--order by--limit--selec
一旦遇到窗口函数,将会返回到 having 后的结果(复制一张表格出来),窗口函数不受 order by、limit 的影响。
八、窗口函数
标准语法:窗口函数 over([partition by 字段名] [order by 字段名 asc|desc])
- over() 中两个子句为可选项,partition by 指定分区依据,order by 指定排序依据
窗口函数不能用于 where 和 having 的筛选,但是能用于 order by 的排序【SQL的运行顺序那里还是有些混乱,稍后再理理】
【排序窗口函数】
- rank()over():跳跃式排序 —— 如 99,99,90,89 为 1,1,3,4
- dense_rank()over():并列连续型排序 —— 如 99,99,90,89 为 1,1,2,3
- row_number()over():连续型排序 —— 如 99,99,90,89 为 1,2,3,4
例题29、rank()over(partition by yr order by votes desc) as posn
- 左边的表是窗口函数复制表格后按照要求打标签,但结果表显示的是根据显示要求排序,再匹配出前面对应的标签(因此才出现标签顺序不一致的情况)
- (相当于新开了一个表,把想算的数值算清楚再匹配回原来的表)
- 窗口函数只能写在 select 语句中
- 窗口函数中的 partition by 子句可以指定数据的分区,和 group by 要去重分组不同的是,partition by 只分区不去重
- 窗口函数中没有 partition by 子句时,即不对数据分区,直接整个表格一个区
- 排序窗口函数中 order by 子句是必选项,窗口函数中的 order by 子句在分区内,依据指定字段和排序方法对数据进行排序
【偏移分析函数】
- lag(字段名,偏移量[,默认值])over():上偏移
- lead(字段名,偏移量[,默认值])over():下偏移
lag(字段名,偏移量[,默认值])over([partition by 字段名] order by 字段名 asc|desc)
lead(字段名,偏移量[,默认值])over([partition by 字段名] order by 字段名 asc|desc)
Tips:
- 偏移分析窗口函数中 order by 子句是必选项
- 可以理解为取字段名这一列(使用偏移窗口函数的单元格)同行对应的数据的偏移位置数据
九、表连接
内连接
基础语法:from 表名1 inner join 表名2 on 表名1.字段名 = 表名2.字段名
(只写 join 默认为 内连接)
左连接
基础语法:from 表名1 left join 表名2 on 表名1.字段名 = 表名2.字段名
右连接
基础语法:from 表名1 right join 表名2 on 表名1.字段名 = 表名2.字段名
两个表的全连接示例:
- inner join 内连接,连接两个表留下同时互相匹配上的行得到一张新表(去除全连接后出现 null 的行)
- left join 左连接,返回左边的表所有行,右边的表只留下匹配上的行
- right join 右连接类似
例题32:from game join eteam on eteam.id = game.team1
赛事编号是来自 game 表的 id 列,但是 game 表和 eteam 表都有 id 列,直接写 select id 数据库无法分辨此 id 列来自于哪一个表,会出现报错。因此需要在 select 语句中,明确一下是哪个表中的 id字段。如 select game.id
例题33:from teacher t left join dept d on t.dept = d.id
可以在表连接语句中给表名替换一个缩略替代语(如 teacher t dept d,之后所有的 teacher 和 dept 都可用 t 和 d 代替)
十、子查询
子查询本身就是一段完整的查询语句,然后用括号英文括号()包裹嵌套在主查询语句中,子查询可以多层嵌套
最常用的子查询运用在 from 和 where 子句中
- 子查询是可以自己正常独立运行的一段完整的查询语句,然后将子查询的查询结果作为主查询的一部分,因此子查询优先于主查询运行
- 对于比较运算符的子查询,要求子查询为标量子查询,即子查询结果为一行一列(相当于一个单元格)
- 对于 in 关键字的子查询,要求子查询为列子查询,即子查询结果为多行一列(单列)
- where 子句中的子查询适用于查询条件无法一步到位,需要先进行一步查询得到结果,基于这个查询结果再进行条件判断的情况
- 例题36:在一段查询语句中 where 子句先于窗口函数运行,因此运行where 子句时还没有posn字段,无法进行条件筛选,运行完窗口函数生成posn 字段后,不会再返回运行 where 子句,因此必须写子查询,优先运行完子查询得到查询结果有 posn列,再作为主查询的筛选条件