首页 > 其他分享 >开窗函数进阶last_value特别地方

开窗函数进阶last_value特别地方

时间:2024-03-22 17:57:41浏览次数:23  
标签:last 进阶 union value order 100 id select

有了开窗函数,让我们做统计方便很多。
row_number(),sum,等常规用法,便不在这里讲。

我们从一个问题开始

with abc as ( select 1 as id union all select 2 union all select 3 union all select 4 ) select id, FIRST_VALUE(id) over(order by id ) as firstid, LAST_VALUE(id) over(order by id) as lastid from abc

看结果 明显第二列我的原意是想取得最后一行的值。即为4

185130486dcdf8e56cc70e5a.webp

FIRST_VALUE 一看就明白了。但last_value 为什么就是当前行的值呢?明明该是4才对啊。

原因在于这两个函数 可以用rows 指定作用域。 而默认的作用域是
RANGE UNBOUNDED PRECEDING AND CURRENT ROW
就是说从窗口的第一行到当前行。 所以last_value 最后一行肯定是当前行了。

知道原因后,只需要改掉行的作用域就可以了。

with abc as ( select 1 as id union all select 2 union all select 3 uno union all select 4 ) select id, FIRST_VALUE(id) over(order by id ) as firstid, LAST_VALUE(id) over(order by id rows between UNBOUNDED PRECEDING AND UNBOUNDED following ) as lastid from abc

185130487ea84aeeae74701d.webp

rows 子句的一些关键字
UNBOUNDED PRECEDING 窗口函数第一行
UNBOUNDED following 窗口函数最后一行
CURRENT ROW 当前行

n PRECEDING 当前行的前几行

所以用开窗函数,一定要注意行的作用域

我们再继续作用域

那窗口函数的行作用域到底哪些呢?

排名函数
rank、ntile、dense_rank、row_number 行的作用域都是全结果集,且不支持指定 rows_range_clause

聚合函数
count、sum,count,max,min等 都支持指定rows_range_clause 但如果不指定order by 则是全表,指定了order by 则行范围默认就是 RANGE UNBOUNDED PRECEDING AND CURRENT ROW

;with abc as ( select 0 as id union all select 1 union all select 2 union all select 3 ) select id, sum(id) over(), count(id)over(), sum(id) over(order by id), count(id)over(order by id), sum(id) over(order by id rows between UNBOUNDED PRECEDING AND UNBOUNDED following ), count(id)over(order by id rows between UNBOUNDED PRECEDING AND UNBOUNDED following ) from abc

分析函数
lag,lead 都不支持 指定rows_range_clause

LAST_VALUE 、FIRST_VALUE 默认就是 RANGE UNBOUNDED PRECEDING AND CURRENT ROW

最后我们再分析一下 rows与range的区别

下面的显示代码为 SQL Server的

declare @t table(ord int,billdate varchar(10),add_value int,dec_value int,end_value int) insert into @t select 1,'期初',0,0,100 union all select 2,'2021-01-01',100,0,0 union all select 3,'2021-01-02',0,100,0 union all select 4,'2021-01-03',0,100,0 union all select 5,'2021-01-04',100,0,0 union all select 5,'2021-01-04',100,0,0 select *,sum(add_value -dec_value + end_value ) over(order by ord) as new_end from @t a

end_value 这个字段要实现流水账的功能,即 end_value = 第一行期初行 end_value + add_value - decvalue

执行结果如图

44.webp

可以看到第5行 NEW_END该为100 而不是200

上面说过。 order by 没有显示给出行的作用域范围。则默认为
RANGE between UNBOUNDED PRECEDING AND CURRENT ROW

我改为显示指定 并且用ROWS关键字

declare @t table(ord int,billdate varchar(10),add_value int,dec_value int,end_value int) insert into @t select 1,'期初',0,0,100 union all select 2,'2021-01-01',100,0,0 union all select 3,'2021-01-02',0,100,0 union all select 4,'2021-01-03',0,100,0 union all select 5,'2021-01-04',100,0,0 union all select 5,'2021-01-04',100,0,0 select *,sum(add_value -dec_value + end_value ) over(order by ord rows between UNBOUNDED PRECEDING AND CURRENT ROW) as new_end from @t a

555.webp
可以看到第5行 new_end结果是我期望的100了。

两个例子可以看出 range 关键字,是以 order by 字段的值 做为基准的。因为最后两行的ord 都 = 5 所以就认为是一样的。

而rows 是行号为基准的。
这就是 rows 与 range的区别

n following 当前行的后几行

转自https://www.modb.pro/db/112099?utm_source=index_ai

标签:last,进阶,union,value,order,100,id,select
From: https://www.cnblogs.com/skynight/p/18090181

相关文章

  • 2023-5-11-elasticsearch使用
    索引操作、数据操作索引操作索引的创建、删除等创建索引PUT/shopping{"acknowledged":true,"shards_acknowledged":true,"index":"shopping"}获取索引详细信息GET/_cat/indices?vhealthstatusindexuuid......
  • Docker-compose安装Elasticsearch启动报错(挂载volume后)
    错误提示:"stacktrace":["org.elasticsearch.bootstrap.StartupException:ElasticsearchException[failedtobindservice];nested:AccessDeniedException[/usr/share/elasticsearch/data/nodes];"docker-compose.yamldocker-compose.yamlversion:......
  • @Autowired,@Resource,@Value,@Lazy注入的核心逻辑原理
    classDefaultListableBeanFactoryextendsAbstractAutowireCapableBeanFactory{@Override@NullablepublicObjectresolveDependency(DependencyDescriptordescriptor,StringrequestingBeanName,Set<String>autowiredBeanNames,TypeConverter......
  • elasticsearch 6.8 常用数据字段类型
    在es中,字段类型主要有以下几种:ArraysBinarydatatypeRangedatatypesBooleandatatypeDatedatatypeGeo-pointdatatypeGeo-ShapedatatypeIPdatatypeKeyworddatatypeNesteddatatypeNumericdatatypesObjectdatatypeTextdatatypeTokencountdatatypePercol......
  • MAC安装elasticsearch-head插件
    1.下载插件源码gitclonehttps://github.com/mobz/elasticsearch-head.git2.进入文件夹npminstall3.安装npminstall4.启动npmrunstart5.访问http://localhost:910......
  • TorchV的RAG实践分享(二):基于ElasticSearch的混合检索实战&原理分析
    概述在昨天员外分享的《TorchV的RAG实践分享(1)——RAG的定位、技术选型和RAG技术文章目录》一文中介绍了TorchV的由来,也分享了我们的几个基线产品和应用架构的方向,我们想的是在创业的过程中,将我们自己的一些产品理念、技术心得都通过公众号发文的方式分享出来,更多的和行业内的专家......
  • DFS进阶——全排列
    通过后续的题目希望大家明白,dfs不仅仅是对图的遍历,他还有很多用法。DFS进阶1——回溯先说一下回溯的板子dfs(){for(......){标记信息dfs()撤销标记}}回溯模板——递归实现排列型枚举题目分析其实就是对1~n的数字全排列,这里就可以用dfs去做,1~n全排......
  • nicerefresh--自动刷新Spring中@Value的值
    nicerefresh:自动刷新Spring项目中@Value的值。@RefreshScope虽然有这个功能,但是,它在很多场景下会失效!而nicerefresh就是为了解决这一问题而产生的。用了nicerefresh,不需要加任何注解,即可自动刷新配置!官网:https://www.yuque.com/knifeblade/opensource/nicerefreshgitee:https://......
  • (45/60)爬楼梯进阶、零钱兑换、完全平方数
    day45爬楼梯进阶卡码网:爬楼梯(第八期模拟笔试)动态规划代码实现/*总和为j总共有dp[j]种方法(可重复选取、排列)dp[j]+=dp[j-nums[i]dp[0]=1;其余为0先背包再物品,正序*/#include<iostream>#include<vector>#include<algorithm>usingnamespacestd;intmain(){......
  • <爬虫部署,进阶Docker>----第十章 探究一下Docker Compose
    前言:        DockerCompose是一个用于定义和运行多容器应用程序的工具,它提供了一种简化和自动化容器编排的方式。在理解DockerCompose的背景之前,让我们先回顾一下容器化技术的发展。容器化技术的出现使得应用程序的部署和管理变得更加轻松和灵活。容器化通过......