盘点4种计算数组中元素值为1的个数方法

Python进阶者
• 阅读 159

大家好,我是热心读者。前几天在群里看到有人问了这样一道题,我觉得对一些新手了解窗口函数很有裨益,因此拿出来以飨读者。

盘点4种计算数组中元素值为1的个数方法

至于为什么要拿窗口函数来说事儿呢?因为目前的数分面试,只要考sql,窗口函数是100%会问的。从另一个侧面来讲,窗口函数是检验你的SQL的试金石,一验一个准,比目前的核酸检测水平都高。

好了,闲言少叙,我们来解题。

窗口函数定义

按照分类来讲,一类是专门的窗口函数:row_number(),rank(),dense_rank()等;一类是聚合函数:sum(),avg()等。

按照功能来讲,窗口函数是在不损失行数的背景下,按照指定维度进行分组,按照指定维度进行排序的一种排序函数,聚合等作用的函数,窗口函数的熟练程度决定了你SQL的熟练程度,而在面试中是一道必考题,在业务实践中也是一道迈不过去的坎儿。

窗口函数表达式

这里以row_number()为例,来说明一下表达式的含义,因为万变不离其宗,对于基础我们要了然于心。

row_number() over([parition by 维度] order by 维度 asc [desc])

[partition by 维度] 该部分可以省略,表按照某指定维度进行分组

order by 维度 该部分不允许为空,表按照某维度进行升序(或降序)排序

row_number()函数是用来分组排序的,排序不重复,此处大家可以百度一下跟rank和dense_rank排序的区别。

我们先“由俭入奢”,从最常规的开始处理。题目被我稍作修改

窗口函数实战——基础版

如图:

[图片上传失败...(image-cc12b1-1740302603356)]

根据题意我们会发现,这里是完成的排序是按照id和cat字段分组,按照time字段进行排序,发现了这个规律我们就套用窗口函数的基本语法,即可完成题目的要求,下面是脚本:

  `#第一步 构造数据  insert into  test values('2020-10-02 12:30:45','A','AAA');  insert into  test values('2020-10-02 12:30:55','A','AAA');  insert into  test values('2020-10-02 14:39:45','A','BBB');  insert into  test values('2020-10-02 14:40:55','A','BBB');  insert into  test values('2020-10-02 15:30:05','A','AAA');  insert into  test values('2020-10-02 16:30:45','B','AAA');  insert into  test values('2020-10-02 17:04:45','B','BBB');    # 脚本  select   time,  id,  cat,  row_number() over(partition by id,cat order by time asc) as rnk  from test  order by time asc  # 加入order by 语句为了让数据展示的更清楚,别无他用` 

看下效果:

[图片上传失败...(image-9ca9b3-1740302603356)]

窗口函数实战——进阶版

具体的题目是这样的:

[图片上传失败...(image-ea40ef-1740302603356)]

具体的题目描述如下:

第一列是事件发生的时间,第二列是用户id,第三列是事件分组,第四列是我想要打的排序,如果事件分组和上一个事件不一致,或者用户id不一致的话,就要重新计数

根据图片和描述的情景,我们发现跟上一道题有一点点差别,就是数据顺序已经按照时间排好了序,如果id和cat相同,则进行顺序排序;如果id和cat不同,则要重新从1进行排序。

思路:

1、要想实现上述效果,也就是需要第三列辅助列跟id和cat一起进行分组,而第三列辅助列应该满足以下:

按照id和cat分组连续,则第三列辅助列应该为相同的值;如果id和cat发生了改变,则第三列辅助列应该随之改变,并且需要保证第三列辅助列在每个分组内的值唯一。

2、如果有了第三列辅助列,那么我们套用窗口函数公式即可将题意中顺序排出来。

以下为脚本:

  `# 1 构造数据 以题一中数据为例    # 2 脚本 a 构造连续排序  # 备注 原题中时间标记为1 2 3 ,而实际中时间肯定为标准的时间戳形式,因此需要通过连续数来构造  # 加with temp1 as这个伪脚本为了下面脚本引用方便而已,实际运行中请忽略  with temp1 as   select   time,  id,  category,  concat_ws('-',id,category) as add_col ,  row_number() over(order by time asc) as order_rnk  -- 按时间顺序计算连续排序,构造连续数序列  -- 此处省略partition by 说明实际中partition可以省略  from test` 

示意如图:

[图片上传失败...(image-d7af10-1740302603356)]

而我们通过这个连续数序列想要判断哪些数是连续的,哪些数又是不连续的,接着看脚本

  `with temp2 as   select  time,  id,  category,  add_col,  order_rnk,  order_rnk-lag(order_rnk,1,order_rnk-1) over(partition by add_col order by time asc) as order_rnk_lag1  from temp1  # 这里需要解释下几个知识点:  # 窗口函数lag可以理解为拖后的意思,即按照指定维度分组,指定维度排序,将某列向下平移n行,空值用第三个参数默认  # 因而本文的意思就是将order_rnk这个连续数序列按照add_col这个辅助列,组内向下平移1行,如果是空值,  # 用 order_rnk-1设置为默认值  # 为什么要这样处理:因为我们第一步配置的连续数序列,相邻两行作差,如果差值为1,则连续,否则说明组内出现了不连续的情况` 

示意如图:

[图片上传失败...(image-fda13c-1740302603356)]

通过红色框,我们可以看出来,我们把同一个add_col内的不连续区分了开来,此时,我们就可以有“山重水复疑无路,柳暗花明又一村”的感觉了,我们把add_col 和order_cnk_lag1再作为一个分组的依据,再排序,题意可解,脚本如下:

  `with temp3 as   select   time,  id,  catgory,  row_number() over(parition by concat(add_col,order_cnk_lag1) order by time asc) as rnk  from temp2` 

以上。

[图片上传失败...(image-ae4918-1740302603356)]

小伙伴们,快快用实践一下吧!如果在学习过程中,有遇到任何问题,欢迎加我好友,我拉你进Python学习交流群共同探讨学习。

点赞
收藏
评论区
推荐文章
Souleigh ✨ Souleigh ✨
3年前
JS - 从执行上下文的角度来理解闭包
今天看到一篇关于闭包的文章,里面有这样一句话“就我而言对于闭包的理解仅止步于一些概念,看到相关代码知道这是个闭包,但闭包能解决哪些问题场景我了解的并不多”,这说的不就是我么,每每在面试中被问及什么是闭包,大部分情况下得到的答复是(至少我以前是)A函数嵌套B函数,B函数使用了A函数的内部变量,且A函数返回B函数,这就是闭包。而往往面试官想要听到的并不是这样的
皕杰报表之UUID
​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为
皕杰报表之自定义函数
当设计器里的函数不能满足你的需求时,你需要自定义一些函数来来满足你的需求。设计器上1.选择【工具栏】【窗口】【首选项】【通用配置】【类加载配置】,在【自定义接口实现类配置】中添加自定义函数实现类,添加方式有两种:一是将编译好的.class文件打成jar包,点击【添加JAR】,将jar包导入;二是点击【添加文件夹】,将包含.class文件的文件夹添加进来
Python进阶者 Python进阶者
1年前
大神们,函数定义到底哪块错了?
大家好,我是皮皮。一、前言前几天在Python白银交流群【王王雪饼】问了一个Python基础的问题,这里拿出来给大家分享下。其实就是一个函数处理的问题,她的函数定义有问题,一开始看半天,都没觉得有问题。二、实现过程这里【姜明松】、【eric】给了一个解决思
Stella981 Stella981
3年前
Qt 单击任务栏图标实现最小化
Qt中对于窗口边框的设置一般用到setWindowFlags函数。voidsetWindowFlags(Qt::WindowFlagstype)如果只setWindowFlags(Qt::FramelessWindowHint);去掉边框,此时会发现,当程序打开后,单击任务栏的按钮,会发现无法最小化,隐藏窗口。解决的方法是:s
Stella981 Stella981
3年前
MFC DestroyWindow[转]
考虑单窗口情况:  假设自己通过new创建了一个窗口对象pWnd,然后pWndCreate。则销毁窗口的调用次序:  1.手工调用pWndDestroyWindow();  2.DestroyWindow会发送WM\_DESTROY;  3.WM\_DESTROY对应的消息处理函数是OnD
Wesley13 Wesley13
3年前
C语言程序真正的启动函数
为什么要用”真正”这个词?因为我们从学C语言开始,都会先明白这个道理,即C语言有且仅有一个main函数,main函数是C语言的入口点和出口点!(可以参考http://www.dotcpp.com/wp/184.htmll)不光C语言如此,C也如此,甚至无论黑窗口的控制台程序和Windows应用程序,都是从main函数或者WinMain函数开始执行,这当
Wesley13 Wesley13
3年前
Flex PopUpManager 弹出窗口居中
今天看到窗口居中弹出,我便想到了Alert,既然Alert每次都能居中弹出,为什么我们自定义的窗口不能居中弹出呢,所以,我查看了下Alert的show方法,放到我的代码中,果然也能居中弹出了,不论布局是如何设计的,下面是主要代码://自定义弹出的窗口大小vartitle:TitleWindownewTitleWindow();
Wesley13 Wesley13
3年前
C++中各种获取窗口句柄的方法
AfxGetMainWndAfxGetMainWnd获取自身窗口句柄HWNDhWndAfxGetMainWnd()m\_hWnd;GetTopWindow函数功能:该函数检查与特定父窗口相联的子窗口z序(Z序:垂直屏幕的方向,即叠放次序),并返回在z序顶部的子窗口的句柄。函数原型:HWNDGetTopWind
Stella981 Stella981
3年前
PostgreSQL窗口函数分析
今天看了一下PostgreSQLrow\_number的实现过程。之前一直好奇窗口函数是什么,原理是什么,今天稍稍解惑。下面就以row\_number为例进行介绍:窗口函数:窗口函数在一组表行中执行计算,这些表行以某种方式与当前行相关。这与使用聚合函数可以完成的计算类型相当。但是,窗口函数不会导致行被分组到单个输出行,就像非窗口聚合调用一样。